/* =====================================================================
   lavinux base: layout and structure only.
   Colours, fonts, borders and other looks live in css/themes/<theme>.css,
   scoped under html[data-theme="<id>"].
   ===================================================================== */

:root {
  /* theme hooks (themes override these) */
  --taskbar-h: 40px;
  --icon-cell-w: 75px; /* Windows XP desktop icon spacing */
  --icon-cell-h: 75px;
  --icon-size: 32px;
  --ambient-top: rgba(90, 140, 220, 0.55); /* light thrown up off the top edge of the screen */
  --ambient-corner: rgba(120, 170, 255, 0.45); /* light pooling at the screen's top corners */
  --ambient-edge: rgba(60, 100, 170, 0.5); /* glow hugging the screen edge (mostly top + sides) */
  --ambient-strength: 0.85; /* opacity of the whole room-light layer */

  /* the 4:3 screen: as big as fits, with a little dark "room" around it.
     Only the width is computed; the height always follows from aspect-ratio: 4 / 3. */
  --room: 3vmin;
  --screen-w: min(calc(100vw - 2 * var(--room)), calc((100vh - 2 * var(--room)) * 4 / 3));
}
@supports (height: 100dvh) {
  /* mobile browsers: size against the visible viewport, not the one behind the URL bar */
  :root { --screen-w: min(calc(100vw - 2 * var(--room)), calc((100dvh - 2 * var(--room)) * 4 / 3)); }
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; height: 100%; overflow: hidden; background: #000; }
body {
  display: grid;
  place-items: center;
  user-select: none;
  -webkit-user-select: none;
}
button { font: inherit; color: inherit; }
input, textarea, select { font: inherit; }
svg { display: block; width: 100%; height: 100%; }

/* ------------------------------------------------------------ ambient room light */
/* The monitor sits in a dark room and its light spills onto the wall around it,
   mostly *upward*: strongest along the top edge and at the top corners, fading
   to shadow toward the floor. Three stacked, static layers fake that:
     1. .ambient-img   a blurred copy of the wallpaper = light coloured by the screen
     2. .ambient-glow  theme-tinted light thrown up off the top edge + top corners
     3. ::after        the lower half of the room falling back into shadow
   Only one element is blurred and nothing re-lays out: opacity breathes, plus a
   brief brightness flicker on theme switch, so it stays cheap. No JS involved. */
#ambient {
  position: fixed; inset: 0; z-index: 0; overflow: hidden; pointer-events: none;
  opacity: var(--ambient-strength);
  transition: opacity 1.2s ease;
  /* where the screen's top edge sits (the % resolves against these viewport-sized layers) */
  --screen-top: calc(50% - var(--screen-w) * 3 / 8);
  --screen-half: calc(var(--screen-w) / 2);
}
/* 1. the blurred wallpaper copy: just a touch bigger than the screen and anchored
   low (transform-origin), so more of it leaks out of the top than the bottom */
#ambient .ambient-img {
  position: absolute; left: 50%; top: 50%;
  width: var(--screen-w); aspect-ratio: 4 / 3;
  translate: -50% -50%;
  transform-origin: 50% 85%;
  scale: 1.1 1.14;
  background: #000 center / cover no-repeat;
  /* vmin blur keeps the spill in proportion on every display size; not brightened,
     because light on a wall is never brighter than the screen throwing it */
  filter: blur(6vmin) saturate(1.4) brightness(.95);
  transition: background-color .3s;
}
/* 2. light thrown up off the top edge, and pooling at the two top corners.
   Anchored to the screen (not the window) so it hugs the monitor at any size. */
#ambient .ambient-glow {
  position: absolute; inset: 0;
  background:
    radial-gradient(calc(var(--screen-w) * .62) calc(var(--screen-w) * .26) at 50% var(--screen-top),
      var(--ambient-top), transparent 72%),
    radial-gradient(calc(var(--screen-w) * .3) calc(var(--screen-w) * .3) at calc(50% - var(--screen-half)) var(--screen-top),
      var(--ambient-corner), transparent 72%),
    radial-gradient(calc(var(--screen-w) * .3) calc(var(--screen-w) * .3) at calc(50% + var(--screen-half)) var(--screen-top),
      var(--ambient-corner), transparent 72%);
  mix-blend-mode: screen;
  animation: ambient-breathe 6s ease-in-out infinite;
}
@keyframes ambient-breathe { 50% { opacity: .82; } }
/* 3. the floor end of the room stays dark, so the light reads as shining *up* */
#ambient::after {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(transparent 30%, rgba(0, 0, 0, .8));
}

/* the room is dark while the boot screen is up, and warms up with the desktop */
body:has(#boot:not(.done)) #ambient { opacity: calc(var(--ambient-strength) * .3); }
/* the room flickers along with the CRT when the theme switches */
body:has(#screen.switching) #ambient { animation: ambient-switch .45s steps(6); }
@keyframes ambient-switch { 30% { filter: brightness(.3); } 60% { filter: brightness(1.3); } }

/* screen on -> BSOD -> off: the room light follows what's on screen.
   [data-theme] lifts the BSOD values above the themes' html[data-theme="<id>"] ones. */
html.is-bsod[data-theme] {
  --ambient-top: rgba(40, 120, 255, .8);
  --ambient-corner: rgba(40, 120, 255, .7);
  --ambient-edge: rgba(20, 90, 220, .7);
  --ambient-strength: .9;
}
html.is-bsod #ambient .ambient-img { background-image: none !important; background-color: #0f6dd6; }
html.is-off #ambient { opacity: 0; }
html.is-off #screen { box-shadow: 0 0 0 1px rgba(255, 255, 255, .04); } /* no light left to spill */

/* ------------------------------------------------------------ the 4:3 screen */
#screen {
  position: relative; z-index: 1;
  width: var(--screen-w);
  aspect-ratio: 4 / 3; /* height follows the width (overflow: hidden stops content stretching it) */
  overflow: hidden;
  background: #000 center / cover no-repeat;
  box-shadow:
    0 0 0 1px rgba(255, 255, 255, .06), /* the glass edge */
    0 -10px 34px -2px var(--ambient-edge), /* glow hugging the edge, nudged up so the bottom stays dim */
    0 -30px 100px 4px var(--ambient-top); /* light thrown upward */
  transition: box-shadow .4s;
}
/* light catching the glass: the top edge and top corners glow a little.
   Plain low-alpha white: identical to mix-blend-mode: screen for white, but cheaper. */
.screen-glare {
  position: absolute; inset: 0; z-index: 9800; pointer-events: none;
  background:
    radial-gradient(28% 22% at 0% 0%, rgba(255, 255, 255, .10), transparent 70%),
    radial-gradient(28% 22% at 100% 0%, rgba(255, 255, 255, .10), transparent 70%),
    linear-gradient(rgba(255, 255, 255, .07), transparent 9%);
  box-shadow: inset 0 1px rgba(255, 255, 255, .12); /* a hairline of light along the top of the glass */
}
#screen.switching { animation: crt-switch .45s steps(6); }
@keyframes crt-switch {
  0% { filter: brightness(2) contrast(.6); }
  30% { filter: brightness(.2); }
  60% { filter: brightness(1.4) saturate(.4); }
  100% { filter: none; }
}
/* no breathing room light or CRT flicker for people who asked for less motion
   (kept after the rules above so it wins the cascade) */
@media (prefers-reduced-motion: reduce) {
  #ambient .ambient-glow, #screen.switching, body:has(#screen.switching) #ambient { animation: none; }
}

/* phones held upright: 4:3 would be tiny, so the screen fills the whole viewport
   and the (now hidden) room light is switched off to save the blur */
@media (max-width: 700px) and (orientation: portrait) {
  :root { --room: 0px; }
  /* 100% (not 100vw) so a fractional viewport width or a scrollbar can never push it over the edge */
  #screen { width: 100%; height: 100vh; height: 100dvh; aspect-ratio: auto; box-shadow: none; }
  #ambient { display: none; }
}

/* ------------------------------------------------------------ boot */
.boot {
  position: absolute; inset: 0; z-index: 9000;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 24px;
  background: #000; color: #fff; cursor: pointer;
  transition: opacity .6s ease;
}
.boot.done { opacity: 0; pointer-events: none; }
.boot-logo { display: flex; align-items: center; gap: 14px; }
.boot-icon { width: 48px; height: 48px; }
.boot-bar { width: 220px; height: 14px; overflow: hidden; }
.boot-bar-fill { height: 100%; width: 40%; animation: boot-slide 1.1s linear infinite; }
@keyframes boot-slide { from { transform: translateX(-100%); } to { transform: translateX(250%); } }

/* ------------------------------------------------------------ workspaces + desktop */
#workspaces { position: absolute; inset: 0 0 var(--taskbar-h) 0; z-index: 1; } /* own stacking context so window z-indexes never cover the taskbar */
.workspace { position: absolute; inset: 0; }

/* XP-style icon grid: 75x75 cells, filled top-to-bottom, then left-to-right */
.desktop-icons {
  position: absolute; inset: 0; padding: 6px 2px;
  display: grid; grid-auto-flow: column;
  grid-template-rows: repeat(auto-fill, var(--icon-cell-h));
  grid-auto-columns: var(--icon-cell-w);
  align-content: start; justify-content: start;
}
.desk-icon {
  width: var(--icon-cell-w); height: var(--icon-cell-h);
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 3px 1px 0; margin: 0; border: 0; background: none; cursor: default;
}
.desk-icon-img { width: var(--icon-size); height: var(--icon-size); flex: none; }
.desk-icon-label {
  max-width: 100%; padding: 0 2px;
  text-align: center; line-height: 1.2; word-break: break-word;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.desk-icon.selected .desk-icon-label, .desk-icon:focus .desk-icon-label { -webkit-line-clamp: 5; }
.desk-icon:focus { outline: none; }

/* ------------------------------------------------------------ windows */
.windows { position: absolute; inset: 0; pointer-events: none; }
.win {
  position: absolute; pointer-events: auto;
  display: flex; flex-direction: column;
  min-width: 0;
}
.win.opening { animation: win-open .18s ease-out; }
.win.closing { animation: win-close .14s ease-in forwards; pointer-events: none; }
.win.minimized { display: none; }
.win.maximized {
  left: 0 !important; top: 0 !important;
  width: 100% !important; height: 100% !important;
}
@keyframes win-open { from { opacity: 0; transform: scale(.94); } }
@keyframes win-close { to { opacity: 0; transform: scale(.96); } }

.win-titlebar {
  position: relative; flex: none;
  display: flex; align-items: center; gap: 6px;
  cursor: default; touch-action: none;
}
.win-icon { width: 16px; height: 16px; flex: none; }
.win-title { flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.win-controls { display: flex; flex: none; }
.win-btn { position: relative; padding: 0; cursor: pointer; }
.win-btn span { position: absolute; inset: 0; margin: auto; }
.win-body {
  position: relative;
  flex: 1; min-height: 0; overflow: auto;
  user-select: text; -webkit-user-select: text;
}
.win-resize {
  position: absolute; right: 0; bottom: 0; width: 14px; height: 14px; z-index: 2;
  cursor: nwse-resize; touch-action: none;
}
.win.maximized .win-resize, .win.no-resize .win-resize { display: none; }

/* ------------------------------------------------------------ taskbar */
.taskbar {
  position: absolute; left: 0; right: 0; bottom: 0; height: var(--taskbar-h); z-index: 5000;
  display: flex; align-items: center; gap: 4px;
}
.start-btn { position: relative; flex: none; display: flex; align-items: center; gap: 4px; cursor: pointer; }
.start-icon { width: 16px; height: 16px; flex: none; }
.task-buttons { flex: 1; min-width: 0; height: 100%; overflow: hidden; }
.task-group { display: flex; align-items: center; gap: 3px; height: 100%; }
.task-btn {
  display: flex; align-items: center; gap: 5px; min-width: 0; flex: 0 1 160px;
  cursor: pointer; text-align: left;
}
.task-icon { width: 16px; height: 16px; flex: none; }
.task-label { min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.tray { display: flex; align-items: center; flex: none; }
.tray-clock { display: flex; flex-direction: column; align-items: center; }

/* ------------------------------------------------------------ start menu */
.start-menu {
  position: absolute; left: 0; bottom: var(--taskbar-h); z-index: 6000;
  display: flex; min-width: 220px;
}
.sm-banner { display: none; }
.sm-main { flex: 1; display: flex; flex-direction: column; min-width: 0; }
.sm-header { display: flex; align-items: center; gap: 8px; }
.sm-avatar { width: 32px; height: 32px; flex: none; }
.sm-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* the profile picture is pixel art: keep its pixels square and sharp at any size */
.about-avatar img { image-rendering: pixelated; }
.sm-avatar img { image-rendering: auto; } /* shrunk below 1x, so smooth looks better here */
.sm-list { list-style: none; margin: 0; padding: 0; }
.sm-item { display: flex; align-items: center; gap: 8px; width: 100%; cursor: pointer; text-align: left; }
.sm-item-icon { width: 24px; height: 24px; flex: none; }
.sm-footer { display: flex; justify-content: flex-end; gap: 4px; }
.sm-power { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.sm-power-icon { width: 20px; height: 20px; flex: none; }

/* ------------------------------------------------------------ shared controls */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 4px; cursor: pointer; text-decoration: none; }
.btn-round { width: 32px; height: 32px; padding: 0; }
.progress { height: 16px; overflow: hidden; }
.progress > div { width: 35%; height: 100%; animation: boot-slide 1.2s linear infinite; }

/* ------------------------------------------------------------ apps: layout only */
/* message box */
.msgbox { display: flex; flex-direction: column; gap: 14px; padding: 14px 16px 12px; min-width: 260px; max-width: 380px; }
.msgbox-row { display: flex; gap: 12px; align-items: flex-start; }
.msgbox-icon { width: 32px; height: 32px; flex: none; }
.msgbox-text { margin: 0; flex: 1; white-space: pre-line; }
.msgbox-buttons { display: flex; justify-content: center; }
.msgbox-buttons .btn { min-width: 76px; }

/* about */
.about { padding: 14px 16px; }
.about-card { display: flex; gap: 14px; align-items: center; }
.about-avatar { width: 80px; height: 80px; flex: none; }
.about-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
.about-name, .about-tag { margin: 0; }
.about-specs { display: grid; grid-template-columns: max-content 1fr; gap: 3px 14px; margin: 12px 0; }
.about-spec { display: contents; }
.about-specs dd { margin: 0; }
.about-bio { margin: 0 0 12px; }
.about-links-title { margin: 0 0 6px; }
.about-links { display: flex; flex-wrap: wrap; gap: 6px; }
.about-link { display: inline-flex; align-items: center; gap: 6px; text-decoration: none; }
.about-link-icon { width: 16px; height: 16px; flex: none; }

/* explorer */
.explorer { display: flex; flex-direction: column; }
.explorer-bar { display: flex; justify-content: space-between; gap: 10px; flex: none; }
.explorer-grid {
  flex: 1; display: grid; grid-template-columns: repeat(auto-fill, var(--icon-cell-w));
  grid-auto-rows: min-content; align-content: start; gap: 4px; padding: 8px; overflow: auto;
}
.explorer[data-folder="pictures"] .explorer-grid { grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 8px; }
.explorer-status { flex: none; }
.explorer-empty { grid-column: 1 / -1; margin: 8px; }
.file-tile {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  padding: 3px 1px; margin: 0; border: 0; background: none; cursor: default; min-width: 0;
}
.file-tile-img { width: var(--icon-size); height: var(--icon-size); flex: none; }
.file-tile-img.thumb { width: 100%; height: auto; aspect-ratio: 4 / 3; }
.file-tile-img.thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.file-tile-label { max-width: 100%; text-align: center; word-break: break-word; line-height: 1.2; }
.file-tile:focus { outline: none; }

/* viewer */
.viewer { display: flex; flex-direction: column; }
.viewer-stage { flex: 1; min-height: 0; display: grid; grid-template: minmax(0, 1fr) / minmax(0, 1fr); place-items: center; padding: 10px; overflow: hidden; }
.viewer-stage img { max-width: 100%; max-height: 100%; object-fit: contain; }
.viewer-bar { display: flex; justify-content: center; align-items: center; gap: 14px; padding: 6px; flex: none; }
.viewer-bar.single .btn { visibility: hidden; }

/* lavpad */
.textedit { display: flex; flex-direction: column; overflow: hidden !important; }
.textedit-menu { display: flex; gap: 2px; flex: none; }
.textedit-menu span { padding: 2px 7px; }
.textedit-text { flex: 1; min-height: 0; border: 0; outline: 0; resize: none; padding: 6px 8px; }

/* paint */
.paint { display: flex; flex-direction: column; user-select: none; overflow: hidden !important; }
.paint-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; padding: 4px 6px; flex: none; }
.paint-tools { display: flex; gap: 2px; }
.paint-tool { width: 28px; height: 28px; padding: 3px; display: grid; place-items: center; cursor: pointer; line-height: 1; }
.paint-tool svg { width: 16px; height: 16px; }
.paint-size { display: flex; align-items: center; gap: 6px; }
.paint-actions { display: flex; gap: 4px; margin-left: auto; }
.paint-area { flex: 1; min-height: 0; overflow: auto; padding: 10px; }
.paint-area canvas { display: block; cursor: crosshair; touch-action: none; }
.paint-palette { display: flex; flex-wrap: wrap; align-items: center; gap: 3px; padding: 4px 6px; flex: none; }
.paint-current { width: 32px; height: 32px; padding: 3px; margin-right: 6px; }
.paint-current span { display: block; width: 100%; height: 100%; }
.paint-swatch { width: 18px; height: 18px; padding: 0; cursor: pointer; background: var(--c); }
.paint-custom input { width: 28px; height: 22px; padding: 0; border: 0; background: none; cursor: pointer; }

/* notes */
.notes { display: flex; overflow: hidden !important; }
.notes-side { width: 160px; flex: none; display: flex; flex-direction: column; }
.notes-side-bar { display: flex; gap: 4px; padding: 5px; }
.notes-list { list-style: none; margin: 0; padding: 4px; overflow: auto; flex: 1; }
.notes-list li { padding: 4px 6px; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.notes-text { flex: 1; min-width: 0; border: 0; outline: 0; resize: none; padding: 10px 12px; }

/* minesweeper */
.mines { padding: 8px; user-select: none; overflow: hidden !important; }
.mines-menu { display: flex; gap: 6px; margin-bottom: 6px; }
.mines-hud { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; padding: 5px 6px; }
.mines-lcd { min-width: 48px; text-align: center; }
.mines-face { width: 34px; height: 34px; padding: 0; display: grid; place-items: center; cursor: pointer; font-size: 18px; line-height: 1; }
.mines-face svg { width: 24px; height: 24px; }
.mines-board {
  --size: 24px;
  display: grid; grid-template-columns: repeat(var(--cols), var(--size));
  width: max-content;
}
.cell {
  width: var(--size); height: var(--size); padding: 0; margin: 0;
  display: grid; place-items: center; cursor: pointer; line-height: 1;
}
.cell svg { width: 16px; height: 16px; }
.cell.open { cursor: default; }

/* terminal */
.term { padding: 6px 8px; cursor: text; }
.term pre { margin: 0; white-space: pre-wrap; font: inherit; }
.term-line { display: flex; gap: 8px; }
.term-ps1 { white-space: nowrap; }
.term-line input { flex: 1; min-width: 0; border: 0; outline: 0; background: none; color: inherit; font: inherit; padding: 0; }

/* lavi32 loader */
.lavi32-dlg { padding: 14px; }
.lavi32-dlg p { margin: 0 0 10px; }

/* ------------------------------------------------------------ powered off */
.off-screen {
  position: absolute; inset: 0; z-index: 9999;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px;
  background: #000; color: #8a9aab;
  font: 14px/1.4 'Segoe UI', Tahoma, sans-serif;
  animation: fade-in .4s ease;
}
.off-power { width: 56px; height: 56px; border: 0; padding: 0; background: none; cursor: pointer; opacity: .8; }
.off-power:hover { opacity: 1; filter: drop-shadow(0 0 10px rgba(255, 255, 255, .5)); }
.off-hint { font-size: 12px; opacity: .5; }
@keyframes fade-in { from { opacity: 0; } }

/* ------------------------------------------------------------ lavi32 crash (same in every theme) */
.crash-lag, .crash-lag * { cursor: progress !important; }
.crash-frozen, .crash-frozen * { cursor: wait !important; }
.crash-lag .win { transition: none; }
.win.ghost { pointer-events: none; animation: none; }
.crash-frozen .win .win-body { filter: contrast(.6) brightness(1.35) grayscale(.4); }
#crash-layer { position: absolute; inset: 0; z-index: 9500; pointer-events: none; }
#crash-layer.freeze { pointer-events: auto; background: rgba(255, 255, 255, .1); }
#crash-layer.bsod {
  pointer-events: auto; cursor: none;
  display: flex; align-items: center;
  background: #0f6dd6; color: #fff;
  font-family: 'Segoe UI Light', 'Segoe UI', Tahoma, sans-serif; font-weight: 300;
}
.bsod-inner { max-width: 760px; padding: 0 9%; }
.bsod-face { font-size: clamp(60px, 11vmin, 120px); line-height: 1; margin-bottom: 3vmin; }
.bsod-inner p { font-size: clamp(14px, 2.2vmin, 22px); margin: 0 0 2.2vmin; }
.bsod-foot { display: flex; gap: 16px; align-items: flex-start; }
.bsod-foot p { font-size: clamp(11px, 1.3vmin, 13px) !important; margin-bottom: 8px !important; }
.bsod-qr {
  width: 80px; height: 80px; flex: none; background: #fff;
  -webkit-mask: repeating-conic-gradient(#000 0 25%, transparent 0 50%) 0 0 / 14px 14px;
          mask: repeating-conic-gradient(#000 0 25%, transparent 0 50%) 0 0 / 14px 14px;
}

/* ------------------------------------------------------------ log-on screen (layout) */
/* the desktop stays hidden until you log on (html starts with .is-login) */
html.is-login #workspaces, html.is-login #taskbar, html.is-login #start-menu { visibility: hidden; }
.login {
  position: absolute; inset: 0; z-index: 8500;
  display: grid; place-items: center;
  transition: opacity .3s ease;
}
.login.done { opacity: 0; pointer-events: none; }
.login.logging-on, .login.logging-on * { cursor: progress !important; }
.login-box { width: min(480px, 94%); }
.login-title { display: flex; align-items: center; gap: 6px; }
.login-title-icon { width: 16px; height: 16px; flex: none; }
/* Win95 layout: picture | message + fields | OK/Cancel stacked on the right */
.login-body { display: flex; gap: 14px; padding: 14px; align-items: flex-start; }
.login-avatar { width: 100px; height: 100px; flex: none; }
.login-avatar img { width: 100%; height: 100%; display: block; object-fit: cover; image-rendering: pixelated; }
.login-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 9px; }
.login-msg, .login-hint { margin: 0; }
.login-row { display: grid; grid-template-columns: 72px 1fr; align-items: center; gap: 6px; }
.login-row input { min-width: 0; width: 100%; }
.login-user { cursor: not-allowed; }
.login-buttons { display: flex; flex-direction: column; gap: 6px; flex: none; }
.login-buttons .btn { min-width: 76px; }
.login-box.shake { animation: login-shake .32s steps(8); }
@keyframes login-shake {
  20% { transform: translateX(-7px); } 40% { transform: translateX(7px); }
  60% { transform: translateX(-4px); } 80% { transform: translateX(4px); }
}
@media (max-width: 520px) {
  .login-body { flex-wrap: wrap; }
  .login-buttons { flex-direction: row; width: 100%; justify-content: flex-end; }
}

/* ------------------------------------------------------------ right-click menu, prompt, saved files (layout) */
.ctx-menu {
  position: absolute; z-index: 7000;
  display: flex; flex-direction: column;
  min-width: 170px;
}
.ctx-item {
  display: flex; align-items: center; justify-content: space-between; gap: 18px;
  width: 100%; margin: 0; border: 0; background: none; cursor: default; text-align: left;
}
.ctx-item.bold .ctx-label { font-weight: bold; }
.ctx-item:disabled { cursor: default; }
.ctx-hint { opacity: .7; font-size: .9em; }
.ctx-item:focus { outline: none; }

.prompt { padding: 14px 16px 12px; min-width: 280px; }
.prompt-form { display: flex; flex-direction: column; gap: 14px; }
.prompt-label { display: flex; flex-direction: column; gap: 5px; }
.prompt-input { width: 100%; min-width: 0; }
.msgbox-buttons { gap: 6px; }

.textedit-status { flex: none; padding: 2px 8px; text-align: right; }

/* files visitors saved: their crushed images show as chunky thumbnails on the desktop */
.desk-icon-img.thumb { width: var(--icon-size); height: var(--icon-size); }
.desk-icon-img.thumb img { width: 100%; height: 100%; display: block; object-fit: cover; image-rendering: pixelated; }
.viewer-stage img.pixelated { width: 100%; height: 100%; object-fit: contain; image-rendering: pixelated; }
/* thumbnails never take the touch themselves: on iOS a long-press on an <img> opens the
   system Save/Copy menu and cancels ours (Rename/Delete) */
.desk-icon-img img, .file-tile-img img { pointer-events: none; -webkit-user-drag: none; -webkit-touch-callout: none; }

/* "news footage" in the photo viewer: scanlines, a glow, and a nervous flicker */
.viewer-stage.tv { position: relative; background: #000; }
.viewer-stage.tv img { filter: contrast(1.15) brightness(1.05); animation: tv-flicker 0.18s steps(2) infinite; }
.viewer-stage.tv::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background:
    repeating-linear-gradient(rgba(0, 0, 0, .35) 0 1px, transparent 1px 3px),
    radial-gradient(ellipse at center, transparent 55%, rgba(0, 0, 0, .55));
}
@keyframes tv-flicker { 50% { opacity: .88; } }
@media (prefers-reduced-motion: reduce) { .viewer-stage.tv img { animation: none; } }
