/* Synfonos — the window's own chrome (D-23).
 *
 * WHY THIS FILE EXISTS. `tauri.conf.json` sets `decorations: false`, so Windows draws no
 * caption bar, no system menu and no minimise/maximise/close. Everything a person uses to
 * move, resize, minimise, maximise or close this window is now drawn here, in the product's
 * own design language, on every screen the shell ships.
 *
 * IT IS FURNITURE, NOT AN ARTBOARD. `app.css`'s `.artboard` is a pixel rebuild of the
 * canvas at a fixed 1440x900 and nothing in it moves. This bar is NOT part of any canvas:
 * it sits ABOVE the artboard, in the 40 px the window used to spend on the Windows caption
 * it no longer has. No canvas coordinate changes, no artboard gains or loses a pixel, and
 * the Ana ekran's own 66 px titlebar (WB:41) is untouched — a caption strip and an app
 * header are two different things and this product now draws both, the way Discord, G Hub
 * and Claude Code's own window do.
 *
 * THE 40 PX IS PAID FOR BY THE WINDOW, NOT BY THE DESIGN. `tauri.conf.json`'s window grew
 * from 1440x900 to 1440x940 and its minimum from 1100x760 to 1100x800, so the artboard
 * still has exactly the height it had before this bar existed. `app.css`'s three zoom
 * buckets moved with it — the comment at their site carries the arithmetic.
 *
 * EVERY COLOUR IS A TOKEN. The one exception, `--wc-danger-ink` below, is a colour this
 * surface needs that has no token of its own — defined once, here, rather than a hex
 * pasted at every call site.
 */

:root {
  /* K-7 (`docs/SAHIBININ-TALIMATLARI.md`, 7 Eyl 21:50): "pc canvası yumuşak kenar
   * olsun ... dışında bir çerçeve olması lazım bir shell gibi ince 2-3px kalınlığında
   * aynı şekilde yumuşak kenarları takip edecek." One radius, read by both the surface
   * that gets rounded and the frame ring that outlines it (below) — a shared variable
   * is what makes "no drift between the two" true by construction instead of by two
   * numbers someone has to remember to keep matched, at every window size and while
   * the window is being resized (both are plain CSS, recomputed every layout pass,
   * nothing pixel-cached). 10px is `main.rs`'s own measured read of the corner Windows
   * 11's DWM already draws around this window (see that file's module doc, "the
   * corners stay round ... and neither is our doing") — matched here so this ring's
   * curve does not visibly disagree with the real window edge DWM is clipping to. */
  --shell-radius: 10px;

  /* Read by `body`'s offset below and by app.css's zoom buckets in prose. One number. */
  --wc-h: 40px;

  /* D-22's update strip, when there is one. It is furniture like the bar above it and is
   * paid for the same way — by pushing `body` down, never by covering the screen. */
  --wcup-h: 42px;

  /* Ink on the close button's filled hover state. `--ink-on-fill` cannot be used: it is
   * #fbfaf8 in the light theme and #14161a in the dark one, and the dark step would put
   * near-black glyphs on `--critical` red. The fill is the same red in both themes, so
   * its ink is one value in both themes. */
  --wc-danger-ink: #fbfaf8;
  /* 23 Sep 2026 · the PRESSED step of that same fill, for the same reason the ink is
   * here: one value, in one place, rather than a hex at the call site. It was written
   * as the literal #b62f2f in the `:active` rule below, and that rule set no ink at all
   * — so a close button pressed from the KEYBOARD (Space, no pointer, so no `:hover` to
   * supply the ink) drew `--ink-2` on dark red: 1.13:1 in light, 2.43:1 in dark. */
  --wc-danger-press: #b62f2f;
}

/* ===== D-29 · text is not selectable unless it is worth selecting ==========
 *
 * THE DEFAULT IS OFF, AND IT IS A DECISION. This window is an instrument: its numbers are
 * readouts, its labels caption controls, and almost nothing on it is text anybody wants to
 * copy. What a drag across it DOES produce is a blue smear over half a fader row, which is
 * the single most common way a desktop app announces that it is a web page. Discord, G Hub
 * and Claude Code's own window all make the same call.
 *
 * IT IS A DEFAULT, NOT A LAW. `Ayarlar -> Görünüm -> Metin seçimi` writes
 * `data-select="on"` on <html> (via `prefs.js`), which turns the whole page back into
 * ordinary selectable text. The preference lives in `%LOCALAPPDATA%\Synfonos\settings.json`,
 * so it survives the window closing — see `src-tauri/src/settings.rs`.
 *
 * THE EXCEPTIONS ARE THE INTERESTING PART, because a rule that also blocks the four things
 * a user genuinely needs to copy is a bug wearing a design decision's clothes. Anything a
 * person has to read out, type somewhere else, or paste into a support message keeps its
 * selection whatever the setting says:
 *   * form fields — an <input> you cannot select inside is broken, not tidy;
 *   * the pairing code (`.esl-code`), which is four digits somebody compares against a
 *     phone and may want to copy;
 *   * the diagnostics bundle's path (`.diagbundle-out`), whose whole purpose is to be
 *     pasted into a message to somebody who can help;
 *   * anything marked `.selectable`, which is how a later screen opts one field back in
 *     without touching this block.
 */
html {
  -webkit-user-select: none;
  user-select: none;
}

html[data-select='on'] {
  -webkit-user-select: text;
  user-select: text;
}

input,
textarea,
[contenteditable='true'],
.selectable,
.esl-code,
.diagbundle-out {
  -webkit-user-select: text;
  user-select: text;
}

/* The I-beam, and ONLY on the three that are static text a user drags across. It is
 * deliberately not on the rule above: every fader on the Ana ekran is an
 * `<input type="range">`, and an I-beam over a slider says "type here" about a control
 * you drag. A range input keeps its own cursor and its own selection behaviour. */
.esl-code,
.diagbundle-out,
.selectable {
  cursor: text;
}
/* A button that happens to sit inside a selectable region is still a button. */
.selectable button,
.diagbundle-out button {
  cursor: default;
}

/* The bar is `position: fixed`, so it takes no space in the flow and has to be given
 * some. Two rules, and the second is the one that is easy to get wrong: the global reset
 * in `app.css` is `content-box`, so `min-height: 100vh` + `padding-top: 40px` would make
 * every page 40 px taller than the window and put a scrollbar on a screen that fits.
 *
 * These land AFTER app.css / settings.css / pairing.css / firstrun.css in every page's
 * <link> order, which is what lets them override those files' own `body` rules without
 * any of them knowing this file exists. */
body {
  padding-top: var(--wc-h);
  min-height: calc(100vh - var(--wc-h));
}

/* K-7's ring, on every screen this shell ships — this file, not app.css, because
 * `pairing.css`/`send.css`/`firstrun.css`/`settings.css` are all deliberately
 * self-contained and do not link app.css (see their own headers), and the frame is a
 * property of the WINDOW, not of any one screen's canvas.
 *
 * WHERE THE FRAME LIVES — the decision this rule makes, in words, because the choice
 * was between two real options and the reasoning does not fit in a property name.
 * Tauri/`tao` gives no supported, safe way to inset the WebView2 surface a few pixels
 * from the true window edge and paint a second colour in the gap — doing that would mean
 * answering `WM_NCCALCSIZE` differently or drawing into the non-client area by hand,
 * both `unsafe` Win32 calls this crate's lints forbid outside `native_dialog` (see
 * `main.rs`'s module doc). A margin-based gap purely in CSS was tried on paper and
 * rejected for a sharper reason: `body`'s own height is already `calc(100vh -
 * var(--wc-h))`, one live number seven screens all read to avoid exactly the "extra
 * canvas outside the window" bug K-1 spent a whole pass fixing (`docs/design/
 * UYGULAMA-KABUGU.md` §6). A second inset margin on top of that calc is a second gap to
 * keep in sync by hand across seven files at every window size — the same class of bug
 * K-1 closed, reopened for a cosmetic ring. So: **the ring is a CSS ring on `body`
 * itself**, drawn with `box-shadow: inset ...` at the surface's own true edge rather
 * than in a gap outside it. `border-radius: inherit` on the pseudo-element ties its
 * curve to `body`'s own `border-radius` — one variable, so the two can never drift
 * apart, at any window size, resizing or not.
 *
 * `body`'s `border-radius` also means our own background is clipped to the same curve
 * DWM already clips the window's real pixels to (`main.rs`'s doc: "Windows 11 rounds
 * it") — belt and braces against the one failure K-7 names by name, a straight
 * background corner showing past the round window edge, if this app's own guess at
 * DWM's radius is ever a pixel or two off from the true one.
 *
 * `pointer-events: none` on the ring — it must never steal a click meant for the
 * titlebar's drag region or the window buttons sitting right at this same edge.
 * `z-index` is the highest this shell ever assigns anything (`.panel` tops out at 5) so
 * the ring is never covered by a slide-in panel or the update strip. */
body {
  border-radius: var(--shell-radius);
  overflow: hidden;
  position: relative;
}
body::after {
  content: '';
  position: fixed;
  inset: 0;
  border-radius: inherit;
  box-shadow: inset 0 0 0 2.5px rgba(20, 22, 26, 0.16);
  pointer-events: none;
  z-index: 2147483647;
}

/* D-22 · with the update strip up, the same two rules with one more bar's worth in them.
 * `ui/update.js` sets `data-update` on <html> when it appends the strip and removes it
 * when it takes it away, so a screen never has to know the strip exists. The strip takes
 * REAL space rather than floating: `app.css`'s `.artboard` is a pixel rebuild of a canvas
 * at a fixed size, and sliding it under a bar would crop the design rather than move it. */
html[data-update='banner'] body {
  padding-top: calc(var(--wc-h) + var(--wcup-h));
  min-height: calc(100vh - var(--wc-h) - var(--wcup-h));
}

/* ===== the bar ============================================================ */

.wc {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  height: var(--wc-h);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: space-between;
  box-sizing: border-box;
  background: var(--raised);
  border-bottom: 1px solid var(--line);
  color: var(--ink-1);
  font-family: var(--font-ui);
  /* A caption bar is not a text surface. Without this, dragging the window selects the
   * wordmark, and the I-beam cursor says "type here" over something you cannot type in. */
  user-select: none;
  -webkit-user-select: none;
  cursor: default;
}

.wc-id {
  display: flex;
  align-items: center;
  gap: 8px;
  padding-left: 12px;
  min-width: 0;
}

/* K-19 · the traced mark (`mark.js`), the same one `index.html`'s header draws, at 16
 * rather than 24. The `.wc-logo .wc-dot { fill: var(--dev-1) }` rule that used to sit on
 * this line is gone with the placeholder that needed it, and nothing else in this
 * directory draws a `.wc-dot`.
 *
 * K-45 · `color: var(--ink-1)` USED TO BE ON THIS LINE AND IS DELIBERATELY GONE. The path
 * no longer paints `currentColor`, so that declaration decided nothing and only invited
 * the next reader to fix the mark's colour here — which is the one place it must not be
 * fixed. There is one rule, it is in `mark.js`, and it reads the ground rather than a
 * token: #14161a is what the owner saw as grey. This file must not set `color` or `fill`
 * on the mark; `mark.test.mjs` fails if it does. */
.wc-logo { display: block; flex: none; }

.wc-name {
  font-size: 13px;
  font-weight: 600;
  letter-spacing: -0.01em;
  flex: none;
}

.wc-sep { color: var(--ink-4); flex: none; }

/* The page's name. Truncates rather than pushing the window controls off the bar: at the
 * 1100 px minimum there is room for all of them, but a longer name added later must not
 * be able to take the close button away from the user. */
.wc-page {
  font-size: 12.5px;
  font-weight: 500;
  color: var(--ink-2);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* ===== the three controls ================================================= */

.wc-controls { display: flex; align-items: stretch; flex: none; height: 100%; }

/* 46 x 40 — Windows' own caption-button hit target, which is what a hand that has used
 * Windows expects to find in this corner. TEMA's 44x44 minimum is a TOUCH rule (rule 5,
 * "telefonda"); this bar exists only on the desktop shell and is never touched. */
.wc-btn {
  width: 46px;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-2);
  background: none;
  border: 0;
  padding: 0;
  cursor: default;
  transition:
    background var(--dur-enter) var(--ease),
    color var(--dur-enter) var(--ease);
}
/* TEMA rule 7: 160 ms in, 220 ms out. A hover that leaves is an exit. */
.wc-btn:not(:hover) { transition-duration: var(--dur-exit); }

.wc-btn:hover { background: var(--sunken); color: var(--ink-1); }
.wc-btn:active { background: var(--line); }

/* The one control whose mistake cannot be undone gets the one colour that means that.
 * `--critical` is otherwise reserved for error borders and error text (tokens.css); this
 * is a deliberate third use and the only one on a chrome control. */
.wc-btn.wc-close:hover { background: var(--critical); color: var(--wc-danger-ink); }
.wc-btn.wc-close:active { background: var(--wc-danger-press); color: var(--wc-danger-ink); }

/* DUR:598 — a visible 2 px ring on every focusable. Inset rather than offset: an outline
 * outside a button flush against the window edge is clipped by the window. */
.wc-btn:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: -2px;
}

.wc-btn svg { display: block; }

/* The maximise button swaps glyph with the window's state; both live in the markup and
 * `chrome.js` toggles which one is drawn. Neither is ever removed from the DOM, so the
 * swap cannot leave the button empty. */
.wc-btn [data-when] { display: none; }
.wc-btn[data-max='off'] [data-when='off'] { display: block; }
.wc-btn[data-max='on'] [data-when='on'] { display: block; }

/* ===== D-22 · the optional-update strip ====================================
 *
 * WHAT IT IS ALLOWED TO BE. A quiet strip, `--sunken` on `--line`, in the caption's own
 * language: no accent fill, no shadow, nothing that reads as an alert. An optional update
 * is not news — `core/evo-update/README.md` §4 asks for *"a quiet prompt"* and one button
 * — and the surface that shouts is the full-window lock, which is a different screen for a
 * different decision.
 *
 * WHAT IT NEVER DOES. It never covers anything (see `body` above), it never appears before
 * the installer is on disk and verified (`Progress::surface` in src-tauri/src/update.rs),
 * and it never appears at all when the update is compulsory — that case is not a strip
 * with a stronger colour, it is `update.html`.
 */

.wcup {
  position: fixed;
  top: var(--wc-h);
  left: 0;
  right: 0;
  height: var(--wcup-h);
  z-index: 99;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 12px;
  box-sizing: border-box;
  background: var(--sunken);
  border-bottom: 1px solid var(--line);
  color: var(--ink-1);
  font-family: var(--font-ui);
  font-size: var(--size-sub);
  user-select: none;
  -webkit-user-select: none;
  cursor: default;
}

.wcup > svg { flex: none; color: var(--ink-2); }

/* Truncates rather than pushing the two buttons off the strip: at the window's 1100 px
 * minimum there is room, and a longer version string added later must not be able to take
 * "Yeniden başlat" away from the user. */
.wcup-text {
  flex: 1;
  min-width: 0;
  font-weight: 500;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.wcup-actions { display: flex; align-items: center; gap: 8px; flex: none; }

.wcup-go,
.wcup-later {
  height: 28px;
  padding: 0 14px;
  border-radius: var(--r-pill);
  border: 1px solid var(--line);
  background: var(--raised);
  color: var(--ink-1);
  font-family: var(--font-ui);
  font-size: var(--size-sub);
  font-weight: 500;
  cursor: default;
  transition: background var(--dur-enter) var(--ease);
}
.wcup-go:not(:hover),
.wcup-later:not(:hover) { transition-duration: var(--dur-exit); }

/* The one action, filled the way `settings.css`'s primary pill is: ink, not accent. */
.wcup-go {
  background: var(--ink-1);
  border-color: var(--ink-1);
  color: var(--ink-on-fill);
  font-weight: 600;
}
.wcup-go:hover { background: var(--fill-hover); }
.wcup-go[disabled] { opacity: 0.45; }

.wcup-later { color: var(--ink-2); }
.wcup-later:hover { background: var(--ground); }

/* DUR:598 again — a visible 2 px ring on every focusable. */
.wcup-go:focus-visible,
.wcup-later:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: var(--focus-offset);
}

/* ===== outside the shell ==================================================
 *
 * These pages open as plain files over any static server — that is deliberate and
 * `index.html`'s header says so, because the design can then be reviewed before a single
 * dependency is added. There is no window to minimise in that mode, so the three controls
 * are drawn and marked unavailable rather than being hidden: a reviewer has to see the
 * bar the user will see. `chrome.js` sets the attribute; nothing else does. */
.wc[data-live='no'] .wc-btn {
  opacity: 0.35;
  pointer-events: none;
}
