/* ── shell.css — the desktop ──────────────────────────────────────────────────
 *
 * Period-correct, not a costume. The bevels are real (1px light top-left, 1px
 * dark bottom-right, the way a raised control was actually drawn), the title
 * bar is the blue-to-cyan gradient, and the taskbar sits at the bottom. What it
 * deliberately does not do is chase the joke: no Comic Sans, no under-
 * construction GIFs, no 3D WordArt. This is the professional half of the
 * product — the phone gets the PDA, which is where the charm lives.
 *
 * Tokens are namespaced --sh-* rather than borrowing feed.css's --y2k-*, so the
 * shell renders correctly whatever order the stylesheets happen to load in.
 */

:root {
  --sh-face:    #d6dde5;
  --sh-lt:      #ffffff;
  --sh-mid:     #c0c8d2;
  --sh-dk:      #7c8794;
  --sh-ink:     #14202e;
  --sh-titleA:  #0a246a;
  --sh-titleB:  #4aa3e8;
  --sh-titleAo: #6b7480;   /* unfocused: grey, so focus is legible at a glance */
  --sh-titleBo: #a8b0ba;
  --sh-deskA:   #1b2b46;
  --sh-deskB:   #0c1422;
  --sh-taskbar: #d6dde5;
}

/* The `hidden` attribute is only `display: none` from the UA stylesheet, so any
   author `display:` rule silently defeats it — and every element here has one.
   This bit twice: minimised windows stayed on screen, and the Desktop button
   showed on phones where it had been hidden. Restated at a specificity that
   actually wins. */
.sh-win[hidden], .sh-menu[hidden], .sh-root [hidden], .fxb-trigger[hidden] { display: none; }

.sh-root {
  position: fixed; inset: 0;
  z-index: 1;
  display: flex; flex-direction: column;
  overflow: hidden;
}

/* ── Desktop surface ─────────────────────────────────────────────────────── */
.sh-desktop {
  position: absolute; inset: 0 0 var(--sh-taskbar-h, 40px) 0;
  padding: 14px;
  display: flex; flex-direction: column; flex-wrap: wrap;
  align-content: flex-start;
  gap: 6px;
  /* The wallpaper is the one asset a generative model is genuinely the right
     tool for: a large soft decorative raster where the whole job is atmosphere.
     The gradient underneath is not a fallback flourish — it is what shows while
     69 KB downloads, and what shows if it never does. */
  /* The wallpaper is the top background LAYER, not a ::before. A pseudo-element
     at z-index:-1 paints behind its parent's own background unless the parent
     establishes a stacking context — which .sh-desktop does not — so the
     gradient below simply covered it. As a layer, an unset --sh-wall resolves
     to `none` and the gradients show through on their own. */
  background:
    var(--sh-wall, none) center / cover no-repeat,
    radial-gradient(120% 90% at 22% 8%, rgba(74, 163, 232, .22), transparent 62%),
    linear-gradient(160deg, var(--sh-deskA), var(--sh-deskB));
}
.sh-icon {
  position: relative;
  width: 92px; padding: 9px 4px 7px;
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: none; border: 1px solid transparent; border-radius: 3px;
  color: #eef3fa; cursor: pointer;
  font: 500 11px/1.3 "Tahoma", "Verdana", system-ui, sans-serif;
  text-align: center;
}
.sh-icon:hover { background: rgba(120, 180, 250, .16); border-color: rgba(150, 200, 255, .3); }
.sh-icon:focus-visible { outline: 1px dotted #fff; outline-offset: -2px; }
.sh-icon-art {
  font-size: 30px; line-height: 1;
  filter: drop-shadow(0 2px 3px rgba(0, 0, 0, .5));
}
/* A desktop icon has to read as an APP at a glance, and a bare line glyph on a
   wallpaper does not — it reads as a annotation. The glass tile gives it the
   weight a pixel icon used to get from its own bevelled face, and it is the
   brand's own material rather than another decade's. */
.sh-icon-img {
  width: 46px; height: 46px;
  display: grid; place-items: center;
  border-radius: 13px;
  color: #f2f6ff;
  background: linear-gradient(155deg, rgba(255, 255, 255, .30), rgba(150, 175, 255, .12));
  border: 1px solid rgba(255, 255, 255, .42);
  backdrop-filter: blur(14px) saturate(150%);
  -webkit-backdrop-filter: blur(14px) saturate(150%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .65),          /* specular rim */
    inset 0 -1px 2px rgba(70, 90, 160, .18),
    0 4px 12px rgba(6, 12, 30, .38);
  transition: transform .16s ease, box-shadow .16s ease, background .16s ease;
}
.sh-icon:hover .sh-icon-img {
  transform: translateY(-1px);
  background: linear-gradient(155deg, rgba(255, 255, 255, .40), rgba(160, 185, 255, .18));
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .8),
    0 7px 18px rgba(6, 12, 30, .45);
}
.sh-icon:active .sh-icon-img { transform: scale(.96); }
.sh-icon-img svg { width: 26px; height: 26px; display: block; }
/* The label carries its own plate rather than relying on a text-shadow. A
   shadow only works against one kind of wallpaper, and there are four here —
   cream schematic paper and near-black ribbons among them. A plate is legible
   on every one of them without anything having to switch. */
.sh-icon-label {
  padding: 1px 5px;
  border-radius: 2px;
  background: rgba(8, 14, 24, .58);
  text-shadow: 0 1px 2px rgba(0, 0, 0, .7);
}
.sh-icon:hover .sh-icon-label { background: rgba(10, 36, 106, .85); }

/* ── Display properties ──────────────────────────────────────────────────── */
/* Same glass as the Start menu it opens from — it was still the old grey panel,
   which read as a different operating system sitting on top of this one. */
.sh-wall {
  position: absolute; left: 8px; bottom: calc(var(--sh-taskbar-h, 40px) + 6px);
  z-index: 2147483002;
  padding: 10px;
  background: linear-gradient(rgba(24, 46, 78, .84), rgba(8, 18, 36, .92));
  -webkit-backdrop-filter: blur(24px) saturate(1.5);
  backdrop-filter: blur(24px) saturate(1.5);
  border: 1px solid rgba(255, 255, 255, .4);
  border-radius: 8px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 20px 50px rgba(0,0,0,.6);
}
.sh-wall-head {
  font: 400 10.5px/1 "Segoe UI", "Tahoma", system-ui, sans-serif;
  letter-spacing: .12em; text-transform: uppercase;
  color: #cfe3f8;
  text-shadow: 0 1px 2px rgba(0,10,30,.8);
  margin-bottom: 9px;
}
.sh-wall-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 7px; }
.sh-wall-opt {
  display: flex; flex-direction: column; gap: 5px;
  padding: 5px;
  background: rgba(255, 255, 255, .07);
  border: 1px solid rgba(255, 255, 255, .18);
  border-radius: 5px;
  cursor: pointer;
  font: 400 10.5px/1 "Segoe UI", "Tahoma", system-ui, sans-serif;
  color: #dbeaf8;
  text-shadow: 0 1px 2px rgba(0,10,30,.8);
}
.sh-wall-opt img {
  width: 104px; height: 58px; object-fit: cover; display: block;
  border-radius: 3px;
  box-shadow: 0 0 0 1px rgba(0,0,0,.5), 0 2px 6px rgba(0,0,0,.45);
}
.sh-wall-opt:hover { background: rgba(255,255,255,.16); border-color: rgba(190,230,255,.45); }
/* The selected one glows rather than being pressed in — Aero showed selection
   with light, where the bevelled era showed it with depth. */
.sh-wall-opt.on {
  background: linear-gradient(rgba(150, 210, 255, .34), rgba(50, 130, 215, .24));
  border-color: rgba(190, 230, 255, .8);
  box-shadow: 0 0 12px rgba(110, 190, 255, .5), inset 0 1px 0 rgba(255,255,255,.4);
}
.sh-menu-sep { height: 1px; margin: 6px 4px; background: rgba(255,255,255,.18); }

/* ── Window layer ────────────────────────────────────────────────────────── */
.sh-windows {
  position: absolute; inset: 0 0 var(--sh-taskbar-h, 40px) 0;
  pointer-events: none;                 /* the desktop stays clickable between windows */
}
/* Aero glass. Three things make it read as Vista rather than as a translucent
   rectangle, and it is all three or none:
     1. The blur SATURATES as well as blurs — Vista's glass pushed colour, which
        is why a wallpaper behind it stayed recognisable instead of turning grey.
     2. A bright 1px rim on the outside and a softer one inside. The frame is lit
        from its own edge, not shaded like a bevel.
     3. A wide, soft, dark drop shadow. Aero windows floated well above the
        desktop; a tight shadow reads as paper. */
.sh-win {
  position: absolute;
  pointer-events: auto;
  display: flex; flex-direction: column;
  min-width: 320px; min-height: 200px;
  padding: 6px 6px 0;                    /* the glass frame around the content */
  background: rgba(150, 190, 235, .28);
  -webkit-backdrop-filter: blur(18px) saturate(1.7);
  backdrop-filter: blur(18px) saturate(1.7);
  border: 1px solid rgba(255, 255, 255, .55);
  border-radius: 9px 9px 4px 4px;
  box-shadow:
    inset 0 0 0 1px rgba(255, 255, 255, .28),
    inset 0 1px 0 rgba(255, 255, 255, .75),
    0 22px 60px rgba(4, 14, 30, .55),
    0 3px 14px rgba(4, 14, 30, .35);
}
/* Focus is carried by the glass getting brighter and the shadow deeper, which
   is how Vista did it — an unfocused window went flat and grey. */
.sh-win:not(.on) {
  background: rgba(140, 150, 165, .22);
  border-color: rgba(255, 255, 255, .3);
  box-shadow: 0 10px 30px rgba(4, 14, 30, .4);
}
.sh-win.sh-maxed { border-radius: 0; padding: 0; }

/* The title bar is part of the glass, not a coloured band on top of it —
   Vista's whole trick. It only adds a specular sweep across the upper half. */
.sh-title {
  position: relative;
  display: flex; align-items: center; gap: 8px;
  padding: 6px 4px 8px 8px;
  background: linear-gradient(rgba(255, 255, 255, .34), rgba(255, 255, 255, .06) 62%, transparent);
  color: #0d2440;
  font: 400 12px/1.3 "Segoe UI", "Frutiger", "Tahoma", system-ui, sans-serif;
  /* White glow behind dark text: Vista's answer to putting a label on glass of
     unknown brightness. Legible over a dark wallpaper and a light one alike. */
  text-shadow: 0 0 6px rgba(255,255,255,.95), 0 0 12px rgba(255,255,255,.8), 0 1px 0 rgba(255,255,255,.9);
  cursor: default;
  user-select: none;
  flex: 0 0 auto;
}
.sh-win:not(.on) .sh-title { color: #46536a; }
.sh-win.sh-maxed .sh-title { padding-left: 10px; }
/* The mark, wherever chrome shows one. Sized per surface so a 24px grid reads
   at 13-16px without the strokes closing up. */
.sh-mark { display: inline-flex; flex: 0 0 auto; align-items: center; justify-content: center; }
.sh-mark svg { display: block; width: 15px; height: 15px; opacity: .92; }
.sh-mark-glyph { font-size: 12px; line-height: 1; }
.sh-title-ico svg { width: 14px; height: 14px; }
.sh-title-ico.sh-mark-glyph { font-size: 13px; }
.sh-menu-item .sh-mark svg { width: 16px; height: 16px; }
/* The title bar is dark ink on bright glass; a full-strength stroke there is
   heavier than the same stroke on the dark taskbar. */
.sh-title-ico svg { opacity: .78; }
.sh-title-text { flex: 1 1 auto; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Glass buttons grouped as one pill, the way Aero clustered them. */
.sh-btns {
  display: flex; gap: 1px; flex: 0 0 auto;
  padding: 1px;
  border-radius: 5px;
  background: rgba(255, 255, 255, .3);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, .45), 0 1px 3px rgba(10, 30, 60, .3);
}
.sh-b {
  width: 27px; height: 18px;
  display: grid; place-items: center;
  font: 400 10px/1 "Segoe UI", "Tahoma", system-ui, sans-serif;
  color: #10304f;
  background: linear-gradient(rgba(255,255,255,.78), rgba(214,232,250,.42) 52%, rgba(150,190,230,.5));
  border: 0;
  border-radius: 3px;
  cursor: pointer;
  transition: background .12s ease;
}
.sh-b:first-child { border-radius: 4px 3px 3px 4px; }
.sh-b:last-child  { border-radius: 3px 4px 4px 3px; }
.sh-b:hover { background: linear-gradient(rgba(255,255,255,.95), rgba(190,225,255,.75) 52%, rgba(140,195,245,.7)); }
.sh-b:active { background: linear-gradient(rgba(120,170,220,.85), rgba(180,215,245,.7)); }
/* Close is the red one, and only on hover — Aero kept it quiet until aimed at. */
.sh-b.sh-x { width: 44px; }
.sh-b.sh-x:hover { background: linear-gradient(rgba(255,150,140,.95), rgba(226,60,45,.9)); color: #fff; }

/* The containing block. `transform` is what makes every position:fixed
   descendant resolve against this box instead of the viewport — it is the one
   declaration the whole windowed editor depends on, so it is not a detail. */
.sh-body {
  position: relative;
  flex: 1 1 auto;
  min-height: 0;
  overflow: hidden;
  /* The containing block. `transform` is what makes every position:fixed
     descendant resolve against this box instead of the viewport — the one
     declaration the whole windowed editor depends on. Not decoration. */
  transform: translateZ(0);
  background: var(--sh-face);
  border-radius: 3px 3px 0 0;
  /* Sunk into the glass frame rather than sitting on it. */
  box-shadow: 0 0 0 1px rgba(10, 40, 80, .35), 0 -1px 6px rgba(10, 30, 60, .25);
}
.sh-win.sh-maxed .sh-body { border-radius: 0; box-shadow: none; }
.sh-grip {
  position: absolute; right: 0; bottom: 0;
  width: 15px; height: 15px;
  cursor: nwse-resize;
  background:
    linear-gradient(135deg, transparent 42%, var(--sh-dk) 42%, var(--sh-dk) 52%, transparent 52%),
    linear-gradient(135deg, transparent 62%, var(--sh-dk) 62%, var(--sh-dk) 72%, transparent 72%);
}
.sh-win.sh-maxed .sh-grip { display: none; }

/* Dragging a window must not select the text under the pointer, and must not
   let the iframe-ish children swallow the pointermove stream. */
body.sh-dragging { user-select: none; }
body.sh-dragging .sh-body { pointer-events: none; }

/* ── Taskbar ─────────────────────────────────────────────────────────────── */
.sh-taskbar {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: var(--sh-taskbar-h, 40px);
  z-index: 2147483000;   /* above every window: the z counter climbs on focus */
  display: flex; align-items: center; gap: 6px;
  padding: 4px 8px;
  /* Same material as the windows, darker and with the blur turned up. */
  background: linear-gradient(rgba(30, 52, 82, .72), rgba(8, 16, 32, .86));
  -webkit-backdrop-filter: blur(20px) saturate(1.5);
  backdrop-filter: blur(20px) saturate(1.5);
  border-top: 1px solid rgba(255, 255, 255, .38);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.22), 0 -3px 18px rgba(0, 0, 0, .5);
}
/* The Start orb. Round, glossy, lit from above with a hard specular cap —
   deliberately the app's own mark rather than Microsoft's flag: working in a
   visual language is a different thing from copying a company's logo. */
.sh-start {
  position: relative;
  flex: 0 0 auto;
  width: 32px; height: 32px; padding: 0;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, .5);
  background:
    radial-gradient(circle at 50% 122%, rgba(120, 220, 255, .95) 0 28%, transparent 30%),
    radial-gradient(circle at 50% 30%, #7fd4ff, #1b7fd0 58%, #0b3f78);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.9),
    inset 0 -6px 10px rgba(4, 30, 60, .55),
    0 2px 6px rgba(0, 0, 0, .5),
    0 0 12px rgba(80, 180, 255, .5);
  color: #eaf6ff;
  cursor: pointer;
}
/* The glass cap over the top half — the detail that makes an orb an orb. */
.sh-start::after {
  content: '';
  position: absolute; left: 14%; right: 14%; top: 6%; height: 42%;
  border-radius: 50% 50% 40% 40% / 60% 60% 40% 40%;
  background: linear-gradient(rgba(255,255,255,.85), rgba(255,255,255,.05));
  pointer-events: none;
}
.sh-start:hover { filter: brightness(1.14); }
.sh-start.on { filter: brightness(1.2); box-shadow: inset 0 2px 6px rgba(4,20,50,.7), 0 0 14px rgba(120,200,255,.75); }
.sh-start > span:not(.sh-start-ico) { display: none; }   /* the orb carries no word */
.sh-start-ico { position: relative; font-size: 13px; text-shadow: 0 1px 2px rgba(0, 20, 50, .7); }

/* Taskbar buttons and menu rows: glass tiles on the dark bar. */
.sh-task, .sh-menu-item {
  display: flex; align-items: center; gap: 7px;
  padding: 6px 11px;
  font: 400 11.5px/1 "Segoe UI", "Tahoma", system-ui, sans-serif;
  color: #eaf3ff;
  background: linear-gradient(rgba(255,255,255,.20), rgba(255,255,255,.05));
  border: 1px solid rgba(255, 255, 255, .26);
  border-radius: 4px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3);
  cursor: pointer;
  text-shadow: 0 1px 2px rgba(0, 10, 30, .7);
}
.sh-task:hover { background: linear-gradient(rgba(255,255,255,.34), rgba(255,255,255,.12)); }
.sh-task.on {
  background: linear-gradient(rgba(160, 215, 255, .5), rgba(60, 140, 220, .34));
  border-color: rgba(190, 230, 255, .6);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5), 0 0 10px rgba(110, 190, 255, .4);
}
.sh-tasks { display: flex; gap: 4px; flex: 1 1 auto; overflow: hidden; }
.sh-task { font-weight: 500; max-width: 190px; }
.sh-task > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sh-tray {
  flex: 0 0 auto; padding: 6px 12px;
  border-radius: 4px;
  border: 1px solid rgba(255, 255, 255, .18);
  background: rgba(255, 255, 255, .07);
}
.sh-clock {
  font: 400 11.5px/1 "Segoe UI", "Tahoma", system-ui, sans-serif;
  color: #eaf3ff;
  text-shadow: 0 1px 2px rgba(0, 10, 30, .8);
  font-variant-numeric: tabular-nums;
}

.sh-menu {
  position: absolute; left: 8px; bottom: calc(var(--sh-taskbar-h, 40px) + 6px);
  /* Was z-index 6, which is BELOW every window — the counter starts at 10 and
     climbs on focus — so the Start menu opened completely hidden behind the
     focused window. It only ever looked right because it was first tested with
     everything minimised. Above the taskbar, which is itself above the windows. */
  z-index: 2147483001;
  display: flex; flex-direction: column; gap: 2px;
  padding: 8px;
  min-width: 230px;
  background: linear-gradient(rgba(24, 46, 78, .82), rgba(8, 18, 36, .9));
  -webkit-backdrop-filter: blur(24px) saturate(1.5);
  backdrop-filter: blur(24px) saturate(1.5);
  border: 1px solid rgba(255, 255, 255, .4);
  border-radius: 8px;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.3), 0 20px 50px rgba(0,0,0,.6);
}
.sh-menu-item { justify-content: flex-start; background: none; border-color: transparent; box-shadow: none; }
.sh-menu-item:hover {
  background: linear-gradient(rgba(150, 210, 255, .42), rgba(50, 130, 215, .3));
  border-color: rgba(190, 230, 255, .55);
}

/* ── Hosting the editor ──────────────────────────────────────────────────── */
/* `transform` re-anchors position:fixed, but it does NOT make viewport units
   container-relative: 100vh stays 100vh. .workspace is the one place that
   matters, and left alone it overflows a small window by hundreds of pixels. */
.sh-body .workspace { height: calc(100% - var(--header-h)); }

/* Apps that already build their own full-screen root — the feed, the video
   editor — are `position: fixed; inset: 0`, which the transform now resolves
   to the window. They only need their backdrop dropped, since the window
   frame is already providing one. */
.sh-hosted { z-index: auto !important; }
.sh-body > .fd-overlay.sh-hosted { background: none; -webkit-backdrop-filter: none; backdrop-filter: none; padding: 0; }
/* Hosted, the feed's own title bar is redundant with the window's — same words,
   same buttons, stacked. It keeps the sort tabs (those are controls, not
   chrome) and drops everything that duplicates the frame. */
.sh-body > .fd-overlay.sh-hosted .fd-head {
  background: var(--sh-face);
  border-bottom: 1px solid var(--sh-dk);
  box-shadow: inset 0 1px 0 var(--sh-lt);
  border-radius: 0;
  padding: 5px 7px;
}
.sh-body > .fd-overlay.sh-hosted .fd-title,
.sh-body > .fd-overlay.sh-hosted .fd-close { display: none; }
.sh-body > .fd-overlay.sh-hosted .fd-sorts { margin-left: 0; }
.sh-body > .fd-overlay.sh-hosted .fd-modal {
  width: 100%; max-width: none; height: 100%; max-height: none;
  border: 0; border-radius: 0; box-shadow: none;
}

/* The desktop is a desktop-only idea; a phone gets the PDA instead. Anything
   narrow falls back to the app as it was, with the shell chrome out of the way. */
@media (max-width: 899px) {
  .sh-taskbar, .sh-desktop { display: none; }
  .sh-windows { inset: 0; }
  .sh-win { position: static; border: 0; border-radius: 0; box-shadow: none; }
  .sh-title { display: none; }
  .sh-body { transform: none; }
  .sh-body .workspace { height: calc(100vh - var(--header-h)); }
}

@media (prefers-reduced-motion: reduce) {
  .sh-win { transition: none; }
}

/* Refusing to un-maximise needs to say so. A window that ignores the button
   silently reads as broken; one that shrugs reads as a rule. */
@keyframes sh-nudge { 0%,100% { transform: none; } 25% { transform: translateX(-3px); } 75% { transform: translateX(3px); } }
.sh-win.sh-nudge { animation: sh-nudge .3s ease; }
@media (prefers-reduced-motion: reduce) { .sh-win.sh-nudge { animation: none; } }

/* A hosted app fills its window completely — it brings its own chrome. */
.sh-frame { display: block; width: 100%; height: 100%; border: 0; background: #1a1a2e; }

/* ── Toasts clear the taskbar ─────────────────────────────────────────────────
 *
 * .lr-toast sits at `bottom: 26px` on `z-index: 100000`, which was fine on a
 * plain page. The taskbar is 40px tall at `z-index: 2147483000`, so on the
 * desktop the bottom third of every toast was painted behind it, hard against
 * the edge of the screen.
 *
 * That is how "SAVE PRESET does nothing" happens: the button DOES answer —
 * "Add at least one effect first" — and the answer is half-swallowed by the
 * taskbar. Measured: toast 835–874, taskbar top 860, 35% covered.
 */
body.sh-on .lr-toast {
  z-index: 2147483003;                              /* over the taskbar and the Start menu */
  bottom: calc(var(--sh-taskbar-h, 40px) + 16px);
}
