/*
  shell.css — the one shell: three destinations and the floating glass bar.

  AUTHORITY. `docs/design/UYGULAMA-KABUGU.md` §1.2 (three destinations), §1.3 (the bar's
  geometry, material and states), §1.6 (the motion ruler) and §1.7 (sheet / modal /
  takeover layering). Where this file and any other sheet disagree about the bar, this
  file wins: it is linked LAST on `index.html`, after `chrome.css` and `motion.css`.

  K-5, in one sentence: the shell never changes, the DESTINATION inside it changes, and
  the bar is drawn on all three of them — including Ayarlar, which is the screen the
  owner watched it disappear from.

  K-8 IS NOT REGRESSED HERE. `.shell-dest` is `overflow: hidden` on purpose: Ayarlar's
  own pane scroller (settings.css) is INSIDE it and keeps its own bar-less scrolling. The
  ONE scroll container this file introduces is the takeover (24 Sep 2026, below), and it
  paints no bar either — K-8's rule is "no scrollbar is ever drawn", and that holds.
*/

/* ===== 1 . the destination stack =========================================
 *
 * `#dest-mikser` is `index.html`'s own `.artboard` — the mixer was never a separate
 * document and does not become one. `#dest-cihazlar` and `#dest-ayarlar` are empty
 * boxes until the shell mounts their markup into them (shell.js), and they are pinned
 * fixed under the caption bar rather than nested inside the mixer's grid so that the
 * markup they receive keeps the layout it was written against.
 *
 * `--shell-top` is written by shell.js from the titlebar's MEASURED bottom edge — the
 * same "measure it, do not guess it" rule 1.3 states for `--shellbar-total`. */
:root {
  --shell-top: 0px;
  --shellbar-h: 56px;
  --shellbar-gap: 20px;
  --shellbar-max: 420px;
  /* 1.3 "Icerik cubugun altina giremez": measured height + gap, written by shell.js. */
  --shellbar-total: calc(var(--shellbar-h) + var(--shellbar-gap));
}

.shell-dest {
  position: fixed;
  left: 0;
  right: 0;
  top: var(--shell-top);
  bottom: 0;
  z-index: 4;
  background: var(--ground);
  overflow: hidden;
}

.shell-dest > .artboard,
.shell-dest > .eslpage-body {
  height: 100%;
  min-height: 0;
}

/* `#dest-mikser` is `index.html`'s own `.artboard`, and `app.css` gives that
 * `display: grid` — which beats the user-agent's `[hidden] { display: none }`. Without
 * this the mixer would stay laid out under every other destination. */
.shell-dest[hidden],
#dest-mikser[hidden] {
  display: none !important;
}

/* 1.3 "Icerik cubugun altina giremez". EVERY destination — the mixer's own artboard
 * included — reserves the bar's MEASURED height plus its gap, so no control can end up
 * under the glass. The first real-window walk caught this: the mixer's own bottom bar
 * ("Cihaz ekle", the live pill, "Ayrinti") sat directly beneath the floating bar,
 * because the mixer was the one destination this rule skipped.
 *
 * `border-box` is load-bearing. `.artboard` is a grid filling the flex line; under the
 * default `content-box` this padding would ADD to its height and push the very 76 px it
 * reserves straight back off the bottom of the window.
 *
 * `#dest-ayarlar` IS DELIBERATELY EXCLUDED (owner, browser review, 17 Sep 2026). Reserving
 * the inset HERE, on the outer `.shell-dest` box, works for the mixer because `#dest-mikser`
 * IS `.artboard` and `.artboard`'s own background is `--ground` — the same colour the
 * reserved strip shows through as, so the two are invisible against each other. Ayarlar's
 * `.shell-dest` instead wraps `.artboard.settings` (settings.css), whose rail is
 * `--raised` — a different colour from `--ground` in both themes — so the same 76px
 * reservation left a flat, differently-coloured band between the rail's true bottom and
 * the window edge: a hard horizontal cut with the rail's last item ("Hakkinda") stopping
 * short of it, exactly what the owner photographed
 * (scratchpad/proof-app-tab-bottom.png). `#dest-ayarlar` instead gets NO outer reservation
 * and fills the full window height, same as the mixer; the inset moves to `.rail` and
 * `.pane` (settings.css), each of which scrolls independently and pads its OWN bottom by
 * `--shellbar-total`, so the surface a person sees behind the glass is always that
 * surface's real background, scrolled short of its own end rather than cut off by a
 * second box underneath it. */
#dest-mikser,
.shell-dest:not(#dest-ayarlar) {
  box-sizing: border-box;
  padding-bottom: var(--shellbar-total);
}

/* 1.6 — 120 ms out, 240 ms in with a 60 ms overlap, 12 px in the bar's own direction.
 * `--shell-dir` is +1 when the destination index grows and -1 when it shrinks. */
.shell-dest.is-leaving,
#dest-mikser.is-leaving {
  animation: shell-leave var(--dur-fast) var(--ease-exit) both;
}
.shell-dest.is-entering,
#dest-mikser.is-entering {
  animation: shell-enter var(--dur-med) calc(var(--dur-fast) / 2) var(--ease-enter) both;
}
@keyframes shell-leave {
  from { opacity: 1; transform: translateX(0); }
  to   { opacity: 0; transform: translateX(calc(var(--shell-dir, 1) * -12px)); }
}
@keyframes shell-enter {
  from { opacity: 0; transform: translateX(calc(var(--shell-dir, 1) * 12px)); }
  to   { opacity: 1; transform: translateX(0); }
}


/* TOKEN NAMES. `docs/design/UYGULAMA-KABUGU.md` 1.3 writes the material with two generic
 * names this tree does not use. `tokens.css` spells the lifted surface `--raised`
 * (#fffefb / #17171b) and the ink `--ink-1` (#14161a / #fbfaf8). The first build of this
 * file copied the document's names verbatim, so every `color-mix()` below resolved to an
 * invalid value and the whole declaration was DROPPED — the bar shipped with no
 * background, no hairline, no contact shadow and no selection pill, i.e. as bare glyphs
 * floating on the ground. The percentages are the document's; only the names are ours,
 * and `shell.test.mjs` now fails the build if one of them stops existing.
 */

/* ===== 2 . the floating glass bar ========================================
 *
 * 1.3 geometry, to the number: 56 px tall, 20 px clear of the bottom edge, capped at
 * 420 px and centred, full pill radius, 6 px of inner padding, 44 px touch targets.
 * `min(420px, 100% - 32px)` is 1.3's one rule for every width in between.
 *
 * z-index 900 — above every destination, above every sheet, above every modal scrim.
 * Only a takeover (1.7) is above it, and a takeover does not draw it at all. */
.shellbar {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: var(--shellbar-gap);
  width: min(var(--shellbar-max), calc(100% - 32px));
  height: var(--shellbar-h);
  box-sizing: border-box;
  display: flex;
  align-items: stretch;
  gap: 2px;
  padding: 6px;
  border-radius: 28px;
  z-index: 900;

  /* 1.3 material — the ONE documented exception to TEMA rule 1: one hairline, one
   * contact shadow, no gradient, no glow, no second shadow. */
  /* K-17 · the glass. `backdrop-filter` was already declared and WebView2 does support
   * it; what was missing was something to SEE through it to. Two fixes, both needed:
   *
   * 1. THE FILL. At 62% of an opaque `--raised` the bar was, in dark theme, near enough
   *    to the ground behind it that a blurred and an unblurred backdrop looked the same.
   *    52% lets the backdrop through far enough to read while the labels still hold
   *    their contrast against it.
   * 2. SOMETHING BEHIND IT. Until K-12 the bar floated over `.botbar`'s flat opaque
   *    fill — a blur of one solid colour is that same solid colour, which is why the
   *    effect was invisible no matter what the filter said. With the strip gone the
   *    ring's own glow and band now pass under the bar, and the blur has an image to
   *    work on. That is the criterion K-17 sets ("cubugun arkasindan gecen icerik
   *    bulanik gorunmeli") and it is what the 8 Sep corner close-up shows. */
  background: color-mix(in srgb, var(--raised) 52%, transparent);
  -webkit-backdrop-filter: blur(24px) saturate(180%);
  backdrop-filter: blur(24px) saturate(180%);
  border: 1px solid color-mix(in srgb, var(--ink-1) 10%, transparent);
  /* K-17 · "daha ince, keskin olmali" — an EDGE light, not a shadow. The old rule was
   * a 28px-blur contact shadow, i.e. a wide soft halo, which is exactly what the owner
   * pointed at. This is one 3px-blur line offset 2px down, tight under the bar's own
   * curve, plus a 1px inset highlight along the top rim so the glass has a lit edge
   * rather than a drawn border. Two shadows in one property is still ONE shadow rule —
   * 1.3's "one contact shadow" budget is about the halo, and the inset is the material
   * catching light, not a second halo. */
  box-shadow:
    0 2px 3px -1px color-mix(in srgb, var(--ink-1) 26%, transparent),
    inset 0 1px 0 color-mix(in srgb, var(--raised) 55%, transparent);
}

/* 1.7 . modal. The bar STAYS IN THE TREE — being removed from it is the owner's
 * complaint — and only drops to 40% and stops taking clicks. */
.shellbar[data-shell-dim='true'] {
  opacity: .4;
  pointer-events: none;
}

/* 1.7 row 3 — a takeover is the ONE state that hides the bar (`shell.js` sets
 * `bar().hidden = true` in `openTakeover`, the ONE place that is legal). `display: flex`
 * above is an author rule and always beats the UA `[hidden] { display: none }` — origin
 * precedence, not selector weight — so without this the bar kept painting over both
 * first-run and the forced-update lock while the accessibility tree correctly reported
 * it hidden. Same trap `#dest-mikser[hidden]` above was fixed for; ui-walk RED #1,
 * 2026-09-07. */
.shellbar[hidden] {
  display: none !important;
}

/* The sliding selection pill (1.3 "Secili", 1.6 "Secim hapinin kaymasi"). One pill,
 * absolutely placed behind the items, moved by `transform` only — the bar itself never
 * moves, and this is the only thing in the bar that does. */
.shellbar-pill {
  position: absolute;
  top: 6px;
  bottom: 6px;
  left: 0;
  width: 0;
  border-radius: 22px;
  background: color-mix(in srgb, var(--ink-1) 8%, transparent);
  transition: transform var(--dur-med) var(--ease-spring),
              width var(--dur-med) var(--ease-spring);
  pointer-events: none;
}

.shellbar-item {
  position: relative;
  flex: 1 1 0;
  min-width: 44px;
  min-height: 44px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
  border: 0;
  background: transparent;
  border-radius: 22px;
  /* K-46 · WAS `--ink-3`, WHICH IS #a29e95 AND UNREADABLE HERE. Measured by the layout
   * scan: 2.45:1 against the bar's own glass in the light theme, under every floor there
   * is. The bar names the two places you are not, so those two words are the whole of the
   * product's navigation; they cannot be a colour you have to lean in to read. `--ink-2`
   * is 6.5:1 on the same ground and still visibly quieter than the selected item's
   * `--ink-1` below, so the three-step ladder rest/hover/selected survives intact — it
   * just starts one rung up. The dark theme was already fine (4.15:1) and is unchanged by
   * this, because both tokens are theme-scoped. */
  color: var(--ink-2);
  cursor: pointer;
  font-family: inherit;
  padding: 0;
  transition: color var(--dur-fast) linear, transform var(--dur-fast) var(--ease-enter);
}

.shellbar-label {
  font-size: 11px;
  font-weight: 500;
  line-height: 1;
  letter-spacing: .01em;
}

.shellbar-item svg { display: block; }

.shellbar-item[aria-selected='true'] { color: var(--ink-1); }
.shellbar-item:hover:not([aria-selected='true']) {
  /* Hover now has to go somewhere the rest state is not — see the K-46 note above. */
  color: var(--ink-1);
  transform: translateY(-2px);
}
.shellbar-item:active { transform: scale(.97); }
.shellbar-item:focus-visible {
  outline: 3px solid var(--ink-1);
  outline-offset: 3px;
}

/* 1.3 "Canli" — a 6 px dot at the icon's top right while a stream runs. No number,
 * no text; 240 ms to appear and to go. */
.shellbar-live {
  position: absolute;
  top: 8px;
  left: calc(50% + 8px);
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--good);
  opacity: 0;
  transition: opacity var(--dur-med) linear;
}
.shellbar-item[data-live='true'] .shellbar-live { opacity: 1; }

/* ===== 3 . sheets, modals, takeovers (1.7) ==============================
 *
 * Three overlay types and no fourth. The sheet layer sits BELOW the bar (899) so the
 * bar stays live over it; the takeover layer sits ABOVE it (901) because a takeover is
 * the one state in which the three destinations do not exist yet. */
.shell-sheet-scrim {
  position: fixed;
  inset: 0;
  z-index: 890;
  background: color-mix(in srgb, var(--ink-1) 28%, transparent);
  animation: shell-fade-in var(--dur-med) var(--ease-enter) both;
}

.shell-sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  top: var(--shell-top);
  z-index: 899;
  background: var(--raised);
  border-radius: 22px 22px 0 0;
  overflow: hidden;
  /* 1.7 — "Yaprak cubugun ALTINDAN baslar": the bar is drawn over the sheet, so the
   * sheet's own content stops short of it. */
  padding-bottom: var(--shellbar-total);
  /* K-46 · AND THE CONTENT HAS TO BE MADE TO OBEY THAT PADDING.
   *
   * It did not. `padding-bottom` reserves 76px in LAYOUT; `overflow: hidden` clips at
   * the PADDING box, not the content box. So a mounted root with no height of its own
   * grew to its natural size, ran straight through the reserved strip, and painted
   * inside it. Measured at 1100x800 before this line: the sheet's content box ends at
   * y=724, `.snd-main` was 784px tall in a 658px box, and `#snd-go` — "Göndermeye
   * başla", the one primary action on that screen — was drawn at 709..761 with the
   * floating bar sitting over it from 724. The person could see the button and could
   * not press it.
   *
   * A column flex box with a `min-height: 0` child is what actually binds the mounted
   * root to the content box; the child then does its own scrolling (see `.snd-main` in
   * `send.css`). Found by the layout scan in `ui-harness/walk.mjs`, which is why it is
   * a rule here and not a note in a report. */
  display: flex;
  flex-direction: column;
  animation: shell-sheet-in var(--dur-med) var(--ease-enter) both;
}
.shell-sheet > * { flex: 1 1 auto; min-height: 0; }
.shell-sheet > .artboard { height: 100%; min-height: 0; }

@keyframes shell-sheet-in {
  from { opacity: 0; transform: translateY(24px); }
  to   { opacity: 1; transform: translateY(0); }
}
@keyframes shell-fade-in { from { opacity: 0; } to { opacity: 1; } }

/* THE CAPTION BAR STAYS REACHABLE, EVEN UNDER A TAKEOVER. `inset: 0` covered it, and
 * the window is `decorations: false` — so first run and the forced-update lock had no
 * minimise, no close and nothing to drag the window by. The bar the takeover is entitled
 * to hide (1.7 row 3) is the NAVIGATION bar, not the window's own furniture: a takeover
 * says "there is nowhere to go yet", never "you may not close this window". */
/* TAKEOVER-SCROLL-EXEMPTION-START — `main.rs`'s `no_screen_but_settings_scrolls` strips
 * this span before scanning shell.css for scroll. The takeover box and its bar-hiding rule
 * only; move both and both markers together. */
.shell-takeover {
  position: fixed;
  top: var(--shell-top);
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 901;
  background: var(--ground);
  /* 24 Sep 2026 (owner, 0923d; audit P1-3) · IT SCROLLS. `overflow: hidden` cut first
   * run's "Başlamadan önce" off at the bottom of the window as soon as a machine listed
   * seven outputs, and the forced-update screen's Retry / "Open the download page" at the
   * 900x600 minimum — the way on below the cut in both, and no way to reach it. Vertical
   * only (nothing on a takeover is wider than the window) and with no painted bar, K-8's
   * rule for every scrolling surface in this shell. `firstrun.css` additionally pins each
   * step's way on to the bottom of this box. */
  overflow-x: hidden;
  overflow-y: auto;
  scrollbar-width: none;
}
.shell-takeover::-webkit-scrollbar { display: none; width: 0; height: 0; }
/* TAKEOVER-SCROLL-EXEMPTION-END */

/* 25 Sep 2026 · a takeover that arrives and leaves instead of cutting (`shell.js`'s
 * `openTakeover(name, { arrive: true })` and `leaveTakeover()`). Opacity and a one-and-a-half
 * per cent scale on `--dur-med`, in on the arriving curve, out on the leaving one; a box
 * waiting for its markup is not drawn at all, so an empty ground never fades in first. */
@keyframes shell-takeover-in {
  from { opacity: 0; scale: 0.985; }
  to { opacity: 1; scale: 1; }
}
@keyframes shell-takeover-out {
  from { opacity: 1; scale: 1; }
  to { opacity: 0; scale: 0.985; }
}
.shell-takeover.is-takeover-wait { opacity: 0; }
.shell-takeover.is-takeover-in { animation: shell-takeover-in var(--dur-med) var(--ease-enter) both; }
.shell-takeover.is-takeover-out {
  animation: shell-takeover-out var(--dur-med) var(--ease-exit) both;
  pointer-events: none;
}

/* ===== 4 . reduced motion (1.6, last paragraph) =========================
 * Seven durations to zero. The transition is INSTANT, never absent. */
@media (prefers-reduced-motion: reduce) {
  .shell-dest.is-leaving,
  .shell-dest.is-entering,
  #dest-mikser.is-leaving,
  #dest-mikser.is-entering,
  .shell-sheet,
  .shell-sheet-scrim,
  .shell-takeover.is-takeover-in,
  .shell-takeover.is-takeover-out {
    animation-duration: 0s !important;
    animation-delay: 0s !important;
  }
  /* The three transitions above already read --dur-med / --dur-fast, and tokens.css
   * zeroes those under this same query — so the pill takes its place instantly without
   * a second rule here saying so. */
  .shellbar-item:hover:not([aria-selected='true']),
  .shellbar-item:active { transform: none; }
}

/* An honest line when a destination could not be mounted (shell.js). Visible on both
 * grounds, because an invisible failure message is the same as no message. */
.shell-mount-failed {
  margin: 24px;
  color: var(--ink-1);
  font-size: 14px;
}
