:root {
  color-scheme: dark;
  font-family: "SFMono-Regular", "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  font-size: 13px;
  background: #0b0d10;
  color: #c3c9d1;
  font-synthesis: none;
  --bg: #0b0d10;
  --panel: #0e1116;
  --raised: #141920;
  --selected: #1b2129;
  --line: #1c222a;
  --line-strong: #2b333d;
  --text: #d7dce3;
  --muted: #7e8794;
  --dim: #59616d;
  /* One accent. Teal only for things that leave this machine, red only for
     failure — the discipline is the point. */
  --accent: #d8a657;
  --accent-dim: #6d5426;
  --teal: #7cb0a8;
  --red: #cc5c52;
  --cyan: #7cb0a8;
  --green: #8fae72;
  --purple: #d8a657;
  --yellow: #d8a657;
  --ui-font: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Segoe UI", sans-serif;
  --menubar-h: 24px;
  --dock-h: 74px;

  /* The desktop's chrome — menu bar, dock, Spotlight, sheets — is translucent
     panels over the wallpaper rather than TUI surfaces, so it carries its own
     handful of tokens. Naming them is what makes a second appearance possible
     without touching a hundred rgba() literals. */
  --glass: rgba(30, 33, 39, 0.88);
  --glass-line: rgba(255, 255, 255, 0.14);
  --glass-hairline: rgba(255, 255, 255, 0.1);
  --glass-hover: rgba(255, 255, 255, 0.14);
  --glass-active: rgba(255, 255, 255, 0.22);
  --glass-text: #f2f4f7;
  --glass-muted: rgba(255, 255, 255, 0.45);
  --glass-dim: rgba(255, 255, 255, 0.3);
  --menubar-bg: rgba(12, 16, 22, 0.55);
  --menubar-text: #eceff3;
  --dock-bg: rgba(190, 200, 214, 0.16);
  --shadow-strong: rgba(0, 0, 0, 0.55);
  --sel: #316dca;
  --sel-ink: #ffffff;
  --doc-face: linear-gradient(180deg, #fdfdfe 0%, #e6e9ee 100%);
  --doc-edge: rgba(0, 0, 0, 0.18);
  --wall-ink: #fff;
  --wall-ink-shadow: 0 1px 3px rgba(0, 0, 0, 0.55);
  --phone-pill: rgba(255, 255, 255, 0.18);
  --phone-card: rgba(28, 33, 41, 0.55);
  --phone-bar: rgba(255, 255, 255, 0.5);
  --wallpaper:
    radial-gradient(120% 90% at 78% 8%, rgba(94, 128, 178, 0.42), transparent 62%),
    radial-gradient(90% 80% at 12% 96%, rgba(58, 44, 92, 0.5), transparent 65%),
    linear-gradient(168deg, #24344a 0%, #16233300 40%),
    linear-gradient(180deg, #1a2635 0%, #101a26 55%, #0a121b 100%);
}

/* Homebrew — the Terminal.app profile of the same name: black paper, green
   phosphor. Not a tinted dark mode; the whole palette collapses onto one hue,
   which is the point. Red survives, because a failure that is green is not a
   failure. */
:root[data-theme="homebrew"] {
  color-scheme: dark;
  background: #000000;
  color: #2bd42b;

  --bg: #000000;
  --panel: #030803;
  --raised: #071207;
  --selected: #0c1d0c;
  --line: #11330f;
  --line-strong: #1c5219;
  --text: #33ff33;
  --muted: #1fa81f;
  --dim: #146b14;
  --accent: #4dff4d;
  --accent-dim: #1c5219;
  --teal: #2bd4a0;
  --red: #ff4d4d;
  --cyan: #2bd4a0;
  --green: #33ff33;
  --purple: #4dff4d;
  --yellow: #9dff4d;

  --glass: rgba(2, 10, 2, 0.92);
  --glass-line: rgba(51, 255, 51, 0.22);
  --glass-hairline: rgba(51, 255, 51, 0.12);
  --glass-hover: rgba(51, 255, 51, 0.14);
  --glass-active: rgba(51, 255, 51, 0.26);
  --glass-text: #33ff33;
  --glass-muted: rgba(51, 255, 51, 0.6);
  --glass-dim: rgba(51, 255, 51, 0.38);
  --menubar-bg: rgba(0, 8, 0, 0.72);
  --menubar-text: #33ff33;
  --dock-bg: rgba(20, 90, 20, 0.18);
  --shadow-strong: rgba(0, 0, 0, 0.8);
  --sel: #1d7a1d;
  --sel-ink: #eaffea;
  --doc-face: linear-gradient(180deg, #07240a 0%, #020c02 100%);
  --doc-edge: rgba(51, 255, 51, 0.35);
  --wall-ink: #33ff33;
  --wall-ink-shadow: 0 0 6px rgba(51, 255, 51, 0.5);
  --phone-pill: rgba(51, 255, 51, 0.16);
  --phone-card: rgba(3, 14, 3, 0.75);
  --phone-bar: rgba(51, 255, 51, 0.45);
  --wallpaper:
    radial-gradient(120% 90% at 78% 8%, rgba(20, 90, 20, 0.5), transparent 62%),
    radial-gradient(90% 80% at 12% 96%, rgba(10, 60, 10, 0.55), transparent 65%),
    linear-gradient(180deg, #020802 0%, #000000 60%);
}

/* Finder is a macOS window, so it takes the theme with everything else. */
:root[data-theme="homebrew"] .finder-window {
  --fdr-chrome: #061006;
  --fdr-body: #000000;
  --fdr-side: #040c04;
  --fdr-line: #11330f;
  --fdr-text: #33ff33;
  --fdr-muted: #1fa81f;
  --fdr-dim: #0f4a0f;
  --fdr-hover: #0c1d0c;
  --fdr-stripe: #040c04;
  --fdr-head: #061006;
  --fdr-side-hover: #0c1d0c;
  --fdr-accent: #4dff4d;
}

/* Light appearance. The terminal keeps its character — a light terminal is
   still a terminal — but the paper goes white and the ink goes dark. */
:root[data-theme="light"] {
  color-scheme: light;
  background: #eceef1;
  color: #2b3038;

  --bg: #e9ebef;
  --panel: #f7f8fa;
  --raised: #eef0f3;
  --selected: #e2e6ec;
  --line: #dce0e6;
  --line-strong: #c2c8d1;
  --text: #23272e;
  --muted: #5c646f;
  --dim: #8a929c;
  --accent: #a5701a;
  --accent-dim: #e5d3ae;
  --teal: #2f7d72;
  --red: #b3392f;
  --cyan: #2f7d72;
  --green: #4a7a2c;
  --purple: #a5701a;
  --yellow: #a5701a;

  --glass: rgba(246, 247, 249, 0.9);
  --glass-line: rgba(0, 0, 0, 0.14);
  --glass-hairline: rgba(0, 0, 0, 0.1);
  --glass-hover: rgba(0, 0, 0, 0.08);
  --glass-active: rgba(0, 0, 0, 0.14);
  --glass-text: #1d2026;
  --glass-muted: rgba(0, 0, 0, 0.5);
  --glass-dim: rgba(0, 0, 0, 0.38);
  --menubar-bg: rgba(245, 246, 248, 0.65);
  --menubar-text: #1d2026;
  --dock-bg: rgba(255, 255, 255, 0.38);
  --shadow-strong: rgba(0, 0, 0, 0.28);
  --sel: #316dca;
  --sel-ink: #ffffff;
  --doc-face: linear-gradient(180deg, #ffffff 0%, #eef0f4 100%);
  --doc-edge: rgba(0, 0, 0, 0.22);
  --wall-ink: #1d2026;
  --wall-ink-shadow: 0 1px 2px rgba(255, 255, 255, 0.6);
  --phone-pill: rgba(255, 255, 255, 0.62);
  --phone-card: rgba(255, 255, 255, 0.62);
  --phone-bar: rgba(0, 0, 0, 0.32);
  --wallpaper:
    radial-gradient(120% 90% at 78% 8%, rgba(150, 185, 235, 0.55), transparent 62%),
    radial-gradient(90% 80% at 12% 96%, rgba(196, 176, 235, 0.5), transparent 65%),
    linear-gradient(168deg, #d8e3f2 0%, #e8eef700 40%),
    linear-gradient(180deg, #dce6f3 0%, #e9edf3 55%, #f2f4f7 100%);
}

* { box-sizing: border-box; }

/* Double-tap zoom off; panning and scrolling untouched. */
html { touch-action: manipulation; }

/* ------------------------------------------------------------- Selection */
/* Chrome is furniture, not text. On a real desktop you cannot drag-select the
   menu bar, the clock, an icon's label or a window's title — being able to is
   the clearest tell that something is a web page. Everything here is furniture;
   the exceptions below put selection back where there is genuinely a document. */
.mac-menubar,
.mac-dock,
.desk-files,
.topbar,
.tabs,
.statusbar,
.filter,
.list-head,
.rows,
.list-total,
.detail-meta,
.krome-tabstrip,
.krome-toolbar,
.krome-bookmarks,
.finder-toolbar,
.finder-sidebar,
.finder-head,
.finder-list,
.finder-status,
.mac-dropdown,
.spotlight-results,
.notif,
.settings,
.help-panel,
.compose-bar,
.editor-bar,
.panel-bar,
.ql-panel > header,
.expose-hits,
.phone,
.phone-topbar,
.power {
  user-select: none;
  -webkit-user-select: none;
}

/* Documents are documents: the detail panes, the shell's output, a Quick Look
   preview and every field you can type into stay selectable and copyable. */
.detail,
.shell-log,
.ql-body,
.set-facts,
input,
textarea {
  user-select: text;
  -webkit-user-select: text;
}

html,
body {
  min-width: 320px;
  min-height: 100%;
  margin: 0;
  overflow: hidden;
  background: var(--bg);
}

button,
a { font: inherit; }

button { border-radius: 0; }

.skip-link {
  position: fixed;
  z-index: 100;
  top: 0;
  left: 0;
  padding: 0.55rem 0.8rem;
  background: var(--cyan);
  color: #000;
  font-weight: 800;
  transform: translateY(-120%);
}

.skip-link:focus { transform: translateY(0); }

.mac-menubar,
.mac-dock {
  display: none;
}

.mac-desktop,
.app-window {
  min-height: 100%;
}

/* Resize grips exist in the markup at every width, but only a desktop has
   windows to resize — anywhere else they would land in the window's grid. */
.win-resize { display: none; }

.window-controls {
  display: flex;
  align-items: center;
  gap: 8px;
}

.window-controls button {
  position: relative;
  width: 12px;
  height: 12px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: #ff5f57;
  line-height: 1;
  cursor: pointer;
}

.window-controls .wc-min { background: #febc2e; }
.window-controls .wc-zoom { background: #28c840; }

/* The hover marks are drawn, not typed. As glyphs they were centered on the
   font's line box rather than on their own ink, which left every one of them
   sitting slightly off inside a 12px circle. */
.window-controls button::before,
.window-controls button::after {
  content: "";
  position: absolute;
  background: rgba(0, 0, 0, 0.62);
  opacity: 0;
  transition: opacity 90ms ease;
}

.window-controls:hover button::before,
.window-controls:hover button::after { opacity: 1; }

/* Close: two strokes crossed on the exact center. */
.wc-close::before,
.wc-close::after {
  top: 50%;
  left: 50%;
  width: 7px;
  height: 1.3px;
  border-radius: 1px;
}

.wc-close::before { transform: translate(-50%, -50%) rotate(45deg); }
.wc-close::after { transform: translate(-50%, -50%) rotate(-45deg); }

/* Minimize: one stroke, same center. */
.wc-min::before {
  top: 50%;
  left: 50%;
  width: 7px;
  height: 1.3px;
  border-radius: 1px;
  transform: translate(-50%, -50%);
}

/* Zoom: the two opposing triangles, mirrored across the center. */
.wc-zoom::before,
.wc-zoom::after {
  width: 3.8px;
  height: 3.8px;
}

.wc-zoom::before {
  top: 2.3px;
  left: 2.3px;
  clip-path: polygon(0 0, 100% 0, 0 100%);
}

.wc-zoom::after {
  right: 2.3px;
  bottom: 2.3px;
  clip-path: polygon(100% 0, 100% 100%, 0 100%);
}

.topbar {
  height: 42px;
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: 0.7rem;
  padding: 0 1rem;
  border-bottom: 1px solid var(--line-strong);
  background: var(--panel);
  white-space: nowrap;
}

.search-mark { color: #aaa; }

.tabs {
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  overflow-x: auto;
  scrollbar-width: none;
}

.tabs::-webkit-scrollbar { display: none; }

.tabs i {
  color: var(--dim);
  font-style: normal;
}

.tab {
  padding: 0.22rem 0.7rem;
  border: 0;
  border-bottom: 2px solid transparent;
  background: transparent;
  color: var(--muted);
  font-weight: 500;
  letter-spacing: 0.02em;
  cursor: pointer;
  white-space: nowrap;
}

.tab span { color: var(--dim); }
.tab:hover { color: var(--text); }

.tab[aria-selected="true"] {
  border-bottom-color: var(--accent);
  color: var(--accent);
}

.tab[aria-selected="true"] span { color: var(--accent-dim); }

.tab:focus-visible,
.list-row:focus-visible,
.open-link:focus-visible,
.brand:focus-visible,
.window-controls button:focus-visible,
.dock-app:focus-visible {
  outline: 1px solid var(--purple);
  outline-offset: 1px;
}

.brand {
  color: var(--muted);
  font-size: 0.78rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-decoration: none;
}

.brand span { color: var(--dim); }

.workspace {
  height: calc(100vh - 64px);
  height: calc(100dvh - 64px);
  overflow: hidden;
}

.workspace-panel {
  height: 100%;
  display: grid;
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
  gap: 10px;
  padding: 10px;
  background: var(--bg);
}

.workspace-panel[hidden] { display: none; }

.list-pane,
.detail-pane {
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  overflow: visible;
  scrollbar-color: var(--line-strong) transparent;
  scrollbar-width: thin;
}

.rows,
.detail {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  scrollbar-color: var(--line-strong) transparent;
  scrollbar-width: thin;
}

/* Each pane is a box with its name sitting on the top rule, the way a real
   terminal UI draws one. */
.list-pane,
.detail-pane {
  position: relative;
  padding: 14px 0 0;
  border: 1px solid var(--line-strong);
  background: var(--panel);
}

.list-pane::before,
.detail-pane::before {
  content: attr(data-title);
  position: absolute;
  top: -0.62em;
  left: 12px;
  padding: 0 6px;
  background: var(--panel);
  color: var(--accent);
  font-size: 0.72rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

/* ------------------------------------------------------------------- Shell */
/* One pane instead of two — a prompt has nothing to show beside it. */
.workspace-panel.is-shell { grid-template-columns: minmax(0, 1fr); }

.shell-pane { cursor: text; }

.shell-scroll {
  flex: 1;
  min-height: 0;
  padding: 6px 12px 10px;
  overflow-y: auto;
  scrollbar-color: var(--line-strong) transparent;
  scrollbar-width: thin;
  font-size: 0.84rem;
  line-height: 1.6;
}

.shell-log { white-space: pre-wrap; overflow-wrap: anywhere; }

.shell-line {
  display: flex;
  align-items: baseline;
  gap: 8px;
}

.shell-prompt {
  flex: none;
  color: var(--accent);
  white-space: nowrap;
}

.shell-line input {
  flex: 1;
  min-width: 0;
  border: 0;
  padding: 0;
  background: transparent;
  color: var(--text);
  caret-color: var(--accent);
  font: inherit;
}

.shell-line input:focus { outline: 0; }

/* The colors the output uses. Same discipline as the rest of the site: amber
   for what the machine says about itself, teal for anything external, red only
   for failure. */
.sh-dim { color: var(--dim); }
.sh-muted { color: var(--muted); }
.sh-accent { color: var(--accent); }
.sh-teal { color: var(--teal); }
.sh-err { color: var(--red); }
.sh-echo { color: var(--muted); }
.sh-echo .shell-prompt { color: var(--accent-dim); }

.shell-run {
  display: flex;
  gap: 8px;
  overflow-wrap: anywhere;
}

.shell-run b { font-weight: 400; color: var(--text); }

.filter {
  height: 26px;
  display: flex;
  align-items: center;
  margin: 4px 10px 8px;
  padding: 0;
  overflow: hidden;
  color: var(--muted);
  font-size: 0.8rem;
  white-space: nowrap;
}

.filter::before {
  content: "❯";
  margin-right: 8px;
  color: var(--accent);
}

/* Hardware carries a fifth column, so it gets its own measure. */
#panel-hardware .list-head,
#panel-hardware .list-row {
  grid-template-columns: 2ch minmax(0, 1fr) 11ch 9ch 8ch;
}

.price { text-align: right; }
.list-row .price { color: var(--muted); }
.list-row.is-selected .price { color: var(--text); }

/* The table closes with its own summary, as a real one does. */
.list-total {
  display: flex;
  justify-content: space-between;
  margin: 4px 12px 8px;
  padding-top: 6px;
  border-top: 1px solid var(--line);
  color: var(--dim);
  font-size: 0.76rem;
}

.list-total b {
  color: var(--accent);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}

/* One line per row, columns measured in characters so they line up exactly. */
.list-head,
.list-row {
  display: grid;
  grid-template-columns: 2ch minmax(0, 1fr) 11ch 10ch;
  gap: 2ch;
  align-items: center;
  padding: 0 12px;
  font-variant-numeric: tabular-nums;
}

.list-head {
  height: 22px;
  margin-bottom: 2px;
  border-bottom: 1px solid var(--line);
  color: var(--dim);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

.list-row {
  width: 100%;
  height: 24px;
  border: 0;
  border-left: 2px solid transparent;
  background: transparent;
  color: var(--muted);
  font-size: 0.82rem;
  text-align: left;
  white-space: nowrap;
  cursor: pointer;
}

.list-row:hover { background: var(--raised); }

.list-row.is-selected {
  border-left-color: var(--accent);
  background: var(--selected);
  color: var(--text);
}

.list-row > span {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
}

.list-row b {
  color: var(--text);
  font-weight: 500;
}

.list-row.is-selected b { color: var(--accent); }

.list-row small {
  margin-left: 1.5ch;
  color: var(--dim);
  font-size: inherit;
}

.state-dot { color: var(--accent-dim); }
.list-row.is-selected .state-dot { color: var(--accent); }
.state-dot.alt { color: var(--teal); }

/* Live status, declared after the selected-row rule and matched with equal
   specificity so the selected row shows its status too — dim until the check
   returns, because "not yet known" is not "down". */
.list-row .state-dot.is-up { color: var(--green); }
.list-row .state-dot.is-down { color: var(--red); }
.badge.is-down { color: var(--red); border-color: var(--red); }

.detail { min-height: 100%; }
.detail[hidden] { display: none; }

.detail-title {
  padding: 4px 12px 10px;
  border-bottom: 1px solid var(--line);
}

.detail-title small {
  display: block;
  color: var(--dim);
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.detail-title h1 {
  margin: 4px 0 0;
  color: var(--text);
  font-size: 0.95rem;
  font-weight: 500;
  line-height: 1.3;
}

.detail-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1.4ch;
  padding: 8px 12px;
  color: var(--dim);
  font-size: 0.76rem;
}

/* Status reads as a tag, not a pill. */
.badge {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  color: var(--accent);
  font-weight: 500;
}

.badge::before { content: "["; color: var(--accent-dim); }
.badge::after { content: "]"; color: var(--accent-dim); }
.badge.purple { color: var(--teal); }

.detail-tabs {
  min-height: 37px;
  display: flex;
  align-items: end;
  gap: 1rem;
  padding: 0 0.8rem;
  border-bottom: 1px solid var(--line);
  color: #777;
  font-size: 0.78rem;
  white-space: nowrap;
}

.detail-tabs > * { padding-bottom: 0.65rem; }

.detail-tabs b {
  border-bottom: 1px solid #ddd;
  color: #ddd;
}

.content-block {
  margin: 14px 12px;
  color: var(--muted);
  font-size: 0.82rem;
  line-height: 1.6;
}

.content-block h2 {
  margin: 0 0 8px;
  color: var(--dim);
  font-size: 0.72rem;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-decoration: none;
  text-transform: uppercase;
}

.content-block p { color: var(--muted); }

.content-block p { max-width: 52rem; }

.content-block a:not(.open-link) {
  color: var(--cyan);
  text-underline-offset: 3px;
}

.content-block q {
  color: #e8e8e8;
  font-style: italic;
}

.source {
  margin-top: 0.9rem;
  color: var(--muted);
  font-size: 0.76rem;
}

/* Product shot. The figure removes itself if the image is missing, so an
   entry without a photo yet reads as if it never had one. */
.product-shot {
  display: flex;
  align-items: center;
  justify-content: center;
  margin: 14px 12px 0;
  padding: 10px;
  border: 1px solid var(--line);
  background: var(--raised);
}

.product-shot img { border-radius: 2px; }

.product-shot img {
  max-width: 100%;
  max-height: 15rem;
  object-fit: contain;
}

.open-link {
  display: inline-block;
  margin-top: 12px;
  padding: 5px 10px;
  border: 1px solid var(--line-strong);
  color: var(--accent);
  font-size: 0.8rem;
  font-weight: 500;
  text-decoration: none;
}

.open-link:hover {
  border-color: var(--accent);
  background: var(--raised);
}

/* Key and value, aligned on a character grid with a dotted leader between —
   the way a spec table is set in a terminal. */
.property {
  display: grid;
  grid-template-columns: 16ch minmax(0, 1fr);
  gap: 1ch;
  padding: 2px 0;
  border: 0;
  line-height: 1.6;
}

.property:last-child { border: 0; }

.property span {
  overflow: hidden;
  color: var(--dim);
  white-space: nowrap;
}

.property span::after {
  content: " ......................................";
  color: var(--line-strong);
}

.property b {
  color: var(--text);
  font-weight: 500;
}

.statusbar {
  position: fixed;
  z-index: 20;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 22px;
  display: grid;
  grid-template-columns: auto auto auto 1fr auto;
  align-items: center;
  gap: 0;
  overflow: hidden;
  border-top: 1px solid var(--line-strong);
  background: var(--panel);
  color: var(--dim);
  font-size: 0.72rem;
  white-space: nowrap;
}

.statusbar > span { padding: 0 10px; }
.statusbar b { color: var(--muted); font-weight: 500; }

.statusbar mark {
  background: none;
  color: var(--accent);
  font-weight: 500;
}

/* The mode block, as every modal editor draws it. */
.mode {
  align-self: stretch;
  display: flex;
  align-items: center;
  background: var(--accent);
  color: #14161a;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

#status-text { color: var(--muted); text-align: right; }
.where { color: var(--muted); }

.help-layer {
  position: fixed;
  z-index: 172;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 7vh 18px;
  background: transparent;
  opacity: 0;
  transition: opacity 180ms ease;
}

.help-layer[hidden] { display: none; }
.help-layer.is-open { opacity: 1; }

.help-panel {
  width: min(460px, 100%);
  max-height: 100%;
  display: grid;
  grid-template-rows: 40px minmax(0, 1fr);
  border: 1px solid var(--glass-line);
  border-radius: 12px;
  background: var(--glass);
  box-shadow: 0 30px 80px var(--shadow-strong);
  font-family: var(--ui-font);
  overflow: hidden;
  backdrop-filter: saturate(180%) blur(26px);
  transform: scale(0.98);
  transition: transform 180ms cubic-bezier(0.32, 0.72, 0, 1);
}

.help-layer.is-open .help-panel { transform: none; }

/* Shared by every draggable panel's title bar. */
.panel-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 12px;
  border-bottom: 1px solid var(--glass-hairline);
  background: var(--glass-hairline);
}

.panel-bar strong { color: var(--glass-text); font-size: 13px; font-weight: 500; }
.panel-bar .is-dead { width: 12px; height: 12px; border-radius: 50%; background: var(--glass-hover); }

.help-body { padding: 6px 14px 14px; overflow-y: auto; }
.help-body dl { margin: 0; }

.help-body dl div {
  display: grid;
  grid-template-columns: 108px minmax(0, 1fr);
  gap: 12px;
  align-items: baseline;
  padding: 7px 0;
  border-bottom: 1px solid var(--glass-hairline);
  font-size: 12.5px;
}

.help-body dl div:last-child { border-bottom: 0; }

.help-body dt {
  color: var(--accent);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 12px;
  text-align: right;
}

.help-body dd { margin: 0; color: var(--glass-text); }

/* A dragged panel is positioned, so its layer's centring no longer applies. */
.settings.is-dragging,
.editor.is-dragging,
.compose.is-dragging,
.ql-panel.is-dragging,
.help-panel.is-dragging { transition: none; }

.panel-bar,
.settings-bar,
.editor-bar,
.compose-bar,
.ql-panel > header { cursor: default; }

::selection { background: var(--purple); color: #000; }

/* --------------------------------------------------------------- Breach ---
   A simulation, triggered on purpose and canceled with Escape. */

.breach {
  position: fixed;
  z-index: 300;
  inset: 0;
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
}

.breach[hidden] { display: none; }

.breach-scanlines {
  position: absolute;
  inset: 0;
  z-index: 2;
  opacity: 0.35;
  pointer-events: none;
  background: repeating-linear-gradient(
    180deg,
    rgba(0, 0, 0, 0.5) 0 1px,
    transparent 1px 3px
  );
}

/* The intruder's terminal. */
.breach-shell {
  position: absolute;
  z-index: 1;
  top: 12vh;
  left: 50%;
  width: min(76rem, 88vw);
  height: min(30rem, 62vh);
  display: grid;
  grid-template-rows: 26px minmax(0, 1fr);
  overflow: hidden;
  border: 1px solid #1c7a3c;
  border-radius: 8px;
  background: rgba(2, 10, 4, 0.96);
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.6), 0 30px 90px rgba(0, 0, 0, 0.7), 0 0 60px rgba(0, 255, 90, 0.12);
  transform: translateX(-50%);
}

.breach-shell header {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 0 10px;
  background: #0b1a0f;
  color: #6fe89a;
  font-size: 11px;
}

.breach-shell header .dot {
  width: 9px;
  height: 9px;
  border-radius: 50%;
  background: #1f4b2c;
}

.breach-shell pre {
  margin: 0;
  padding: 10px 14px;
  overflow: hidden;
  color: #45f07a;
  font-size: 12.5px;
  line-height: 1.45;
  text-shadow: 0 0 8px rgba(69, 240, 122, 0.55);
  white-space: pre-wrap;
  word-break: break-word;
}

.breach-log-warn { color: #ffd166; }
.breach-log-bad { color: #ff5d5d; }
.breach-cursor { animation: breach-blink 1s steps(1) infinite; }

@keyframes breach-blink { 50% { opacity: 0; } }

/* The desktop's own reaction. */
.mac-desktop.is-breached { animation: breach-shake 260ms infinite; }

.mac-desktop.is-breached::after {
  content: "";
  position: fixed;
  z-index: 45;
  inset: 0;
  background: radial-gradient(80% 60% at 50% 40%, rgba(255, 0, 0, 0.22), rgba(60, 0, 0, 0.55));
  mix-blend-mode: screen;
  pointer-events: none;
  animation: breach-pulse 1.4s ease-in-out infinite;
}

.mac-desktop.is-breached .app-window { animation: breach-glitch 3.2s infinite; }

@keyframes breach-shake {
  0%, 100% { transform: translate(0, 0); }
  25% { transform: translate(1px, -1px); }
  50% { transform: translate(-1px, 1px); }
  75% { transform: translate(1px, 1px); }
}

@keyframes breach-pulse {
  0%, 100% { opacity: 0.55; }
  50% { opacity: 0.9; }
}

@keyframes breach-glitch {
  0%, 92%, 100% { filter: none; transform: none; }
  93% { filter: hue-rotate(90deg) saturate(2); transform: translateX(-3px); }
  95% { filter: invert(1); transform: translateX(4px); }
  97% { filter: none; transform: translateX(-2px); }
}

/* The ransom note. */
.breach-ransom {
  position: absolute;
  z-index: 3;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 1.1rem;
  padding: 6vh 8vw;
  overflow: auto;
  background:
    radial-gradient(70% 55% at 50% 35%, rgba(120, 0, 0, 0.55), transparent 70%),
    rgba(4, 0, 0, 0.97);
  color: #ffd9d9;
  text-align: center;
}

.breach-ransom[hidden] { display: none; }

.breach-skull {
  font-size: clamp(3rem, 9vw, 6rem);
  line-height: 1;
  color: #ff3b3b;
  text-shadow: 0 0 40px rgba(255, 40, 40, 0.7);
  animation: breach-pulse 2s ease-in-out infinite;
}

.breach-ransom h2 {
  position: relative;
  max-width: 22ch;
  margin: 0;
  color: #ff4242;
  font-size: clamp(1.5rem, 4.4vw, 3rem);
  letter-spacing: 0.02em;
  line-height: 1.1;
}

/* Chromatic split, the way a bad signal looks. */
.breach-ransom h2::before,
.breach-ransom h2::after {
  content: attr(data-text);
  position: absolute;
  inset: 0;
  opacity: 0.75;
}

.breach-ransom h2::before { color: #00fff2; animation: breach-split-a 2.4s infinite; }
.breach-ransom h2::after { color: #ff00c8; animation: breach-split-b 3.1s infinite; }

@keyframes breach-split-a {
  0%, 96%, 100% { transform: none; opacity: 0; }
  97% { transform: translate(-3px, 1px); opacity: 0.8; }
  99% { transform: translate(2px, -1px); opacity: 0.6; }
}

@keyframes breach-split-b {
  0%, 94%, 100% { transform: none; opacity: 0; }
  95% { transform: translate(3px, -2px); opacity: 0.8; }
  98% { transform: translate(-2px, 1px); opacity: 0.5; }
}

.breach-sub {
  max-width: 46ch;
  margin: 0;
  color: #ffb3b3;
  font-size: 0.9rem;
  line-height: 1.6;
}

.breach-meta {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 0.8rem 2rem;
  margin-top: 0.4rem;
  padding: 0.9rem 1.2rem;
  border: 1px solid rgba(255, 60, 60, 0.45);
  background: rgba(40, 0, 0, 0.6);
}

.breach-meta span {
  display: block;
  color: #ff8f8f;
  font-size: 0.66rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
}

.breach-meta b {
  color: #fff;
  font-size: 0.95rem;
  word-break: break-all;
}

.breach-exit {
  margin-top: 1rem;
  padding: 0.75rem 1.3rem;
  border: 1px solid rgba(255, 255, 255, 0.35);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  font-family: var(--ui-font);
  font-size: 0.85rem;
  cursor: pointer;
}

.breach-exit:hover { background: rgba(255, 255, 255, 0.2); }

/* Motion is the whole effect, but not at the cost of making someone ill. */
@media (prefers-reduced-motion: reduce) {
  .mac-desktop.is-breached,
  .mac-desktop.is-breached::after,
  .mac-desktop.is-breached .app-window,
  .breach-skull,
  .breach-ransom h2::before,
  .breach-ransom h2::after { animation: none; }
}

/* --------------------------------------------------------------- Finder ---
   A third window, in Finder's own colors rather than the terminal's. */

.finder-window {
  --fdr-chrome: #2c2c2e;
  --fdr-body: #1e1e20;
  --fdr-side: #262628;
  --fdr-line: #3a3a3d;
  --fdr-text: #ececf0;
  --fdr-muted: #9a9aa0;
  --fdr-dim: #5c5c61;
  --fdr-hover: #2e2e31;
  --fdr-stripe: #232325;
  --fdr-head: #242426;
  --fdr-side-hover: #333336;
  --fdr-accent: #6fa8ff;
  position: fixed;
  z-index: 60;
  inset: 0;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: 44px minmax(0, 1fr) 24px;
  overflow: hidden;
  background: var(--fdr-body);
  color: var(--fdr-text);
  font-family: var(--ui-font);
  font-size: 12.5px;
}

/* Finder is a macOS window, so it follows the appearance — unlike Krome, which
   is a Chrome clone and keeps Chrome's own theme. */
:root[data-theme="light"] .finder-window {
  --fdr-chrome: #ebebed;
  --fdr-body: #ffffff;
  --fdr-side: #f4f4f6;
  --fdr-line: #dcdce0;
  --fdr-text: #1d1d1f;
  --fdr-muted: #6e6e73;
  --fdr-dim: #b0b0b6;
  --fdr-hover: #ececed;
  --fdr-stripe: #f7f7f9;
  --fdr-head: #f2f2f4;
  --fdr-side-hover: #e3e3e6;
  --fdr-accent: #2b6cd4;
}

.finder-window > * { min-width: 0; }

.finder-window.is-closed,
.finder-window.is-hidden { display: none; }

/* -------------------------------------------------------------- Time Machine */
/* A stack of real backups receding into a starfield. The depth is genuine 3D —
   perspective on the stage, translateZ on the cards — so the parallax between
   them holds while you move through the stack. */
.tm-layer {
  position: fixed;
  z-index: 300;
  inset: 0;
  opacity: 0;
  transition: opacity 240ms ease;
  font-family: var(--ui-font);
  color: #f2f4f7;
}

.tm-layer.is-open { opacity: 1; }
.tm-layer[hidden] { display: none; }

.tm-stars {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.tm-stage {
  position: absolute;
  inset: 0 200px 96px 0;
  perspective: 1500px;
  transform-style: preserve-3d;
}

.tm-card {
  position: absolute;
  left: 50%;
  top: 50%;
  width: min(620px, 62vw);
  height: min(400px, 52vh);
  display: grid;
  grid-template-rows: 30px minmax(0, 1fr) 26px;
  overflow: hidden;
  border: 1px solid rgba(255, 255, 255, 0.22);
  border-radius: 12px;
  background: linear-gradient(160deg, #2f3d57, #4b3f63 55%, #6b5573);
  box-shadow: 0 30px 80px rgba(0, 0, 0, 0.6);
  transition: transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1), opacity 320ms ease;
  cursor: pointer;
}

.tm-card.is-current {
  border-color: rgba(255, 255, 255, 0.5);
  cursor: default;
}

.tm-card-head {
  display: grid;
  place-items: center;
  background: rgba(10, 14, 22, 0.55);
  font-size: 11.5px;
  letter-spacing: 0.02em;
}

.tm-card-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(74px, 1fr));
  align-content: start;
  gap: 10px;
  padding: 14px;
  overflow: hidden;
}

.tm-card-file {
  display: grid;
  justify-items: center;
  gap: 4px;
  min-width: 0;
}

.tm-card-icon {
  display: grid;
  place-items: center;
  width: 38px;
  height: 44px;
  border-radius: 3px;
  background: rgba(255, 255, 255, 0.92);
  color: #4a4a4f;
  font-size: 15px;
}

.tm-card-icon.is-thumb { background: none; }

.tm-card-icon img {
  max-width: 100%;
  max-height: 100%;
  border-radius: 2px;
  object-fit: contain;
}

.tm-card-file small {
  max-width: 74px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font-size: 10.5px;
}

.tm-card-empty {
  grid-column: 1 / -1;
  margin: 0;
  padding: 40px 0;
  color: rgba(255, 255, 255, 0.6);
  text-align: center;
}

.tm-card-foot {
  display: grid;
  place-items: center;
  background: rgba(10, 14, 22, 0.5);
  color: rgba(255, 255, 255, 0.7);
  font-size: 10.5px;
}

/* The timeline, as a ladder of dates down the right edge. */
.tm-rail {
  position: absolute;
  z-index: 110;
  top: 12vh;
  right: 26px;
  bottom: 110px;
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  gap: 2px;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow: hidden;
}

.tm-tick button {
  display: block;
  width: 150px;
  padding: 3px 10px;
  border: 0;
  border-right: 2px solid rgba(255, 255, 255, 0.25);
  background: none;
  color: rgba(255, 255, 255, 0.55);
  font: inherit;
  font-size: 11px;
  text-align: right;
  cursor: pointer;
}

.tm-tick button:hover { color: #fff; }

.tm-tick.is-current button {
  border-right-color: #fff;
  color: #fff;
  font-weight: 600;
}

.tm-bar {
  position: absolute;
  z-index: 110;
  right: 0;
  bottom: 0;
  left: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 20px;
  padding: 18px 30px 26px;
  background: linear-gradient(to top, rgba(4, 6, 12, 0.85), transparent);
}

.tm-when {
  margin: 0;
  font-size: 15px;
}

.tm-buttons {
  display: flex;
  gap: 10px;
}

.tm-buttons button {
  min-width: 96px;
  padding: 6px 16px;
  border: 1px solid rgba(255, 255, 255, 0.3);
  border-radius: 7px;
  background: rgba(255, 255, 255, 0.14);
  color: #fff;
  font: inherit;
  font-size: 13px;
  cursor: pointer;
}

.tm-buttons button:hover { background: rgba(255, 255, 255, 0.24); }

.tm-buttons button.is-default {
  border-color: transparent;
  background: var(--sel);
}

.tm-buttons button:disabled {
  opacity: 0.4;
  cursor: default;
}

/* Nothing behind it should react while the machine is up. */
body.is-timemachine .mac-desktop { pointer-events: none; }

@media (max-width: 900px) {
  .tm-layer { display: none; }
}

/* ------------------------------------------------------------ Dropped files */
/* The desktop accepts files off the visitor's own machine. The shade is what
   tells them that before they let go. */
.desk-drop {
  position: fixed;
  z-index: 200;
  inset: var(--menubar-h) 12px calc(var(--dock-h) + 8px);
  display: grid;
  place-items: center;
  border: 2px dashed var(--glass-line);
  border-radius: 14px;
  background: rgba(20, 24, 32, 0.28);
  backdrop-filter: blur(2px);
  pointer-events: none;
}

/* `hidden` only wins over a display of its own if it is said again here. */
.desk-drop[hidden] { display: none; }

.desk-drop-mark {
  padding: 8px 18px;
  border-radius: 999px;
  background: var(--glass);
  color: var(--glass-text);
  font-family: var(--ui-font);
  font-size: 13px;
  box-shadow: 0 10px 30px var(--shadow-strong);
}

/* A picture is its own icon, sized to the same box the folder art uses. */
.desk-icon.is-thumb {
  background: none;
  border: 0;
  box-shadow: none;
}

.desk-thumb {
  max-width: 100%;
  max-height: 100%;
  border-radius: 3px;
  object-fit: contain;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.45);
}

.ql-image {
  max-width: 100%;
  max-height: 52vh;
  margin: 0 auto;
  border-radius: 4px;
  object-fit: contain;
}

.ql-none {
  padding: 28px 0;
  color: var(--muted);
  text-align: center;
}

/* ---------------------------------------------------- Activity Monitor */
/* Shares the Finder's palette — it is the same kind of window — with its own
   grid because the columns change from tab to tab. */
.activity-window {
  --am-chrome: #2c2c2e;
  --am-body: #1c1c1e;
  --am-line: #3a3a3d;
  --am-text: #ececf0;
  --am-muted: #9a9aa0;
  --am-head: #242426;
  --am-stripe: #222224;
  --am-hover: #2e2e31;
  --am-graph: #34c759;
  --am-graph-soft: rgba(52, 199, 89, 0.16);
  --am-grid: rgba(255, 255, 255, 0.08);
  position: fixed;
  z-index: 62;
  inset: 0;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: 52px minmax(0, 1fr) auto;
  overflow: hidden;
  background: var(--am-body);
  color: var(--am-text);
  font-family: var(--ui-font);
  font-size: 12px;
}

:root[data-theme="light"] .activity-window {
  --am-chrome: #ebebed;
  --am-body: #ffffff;
  --am-line: #dcdce0;
  --am-text: #1d1d1f;
  --am-muted: #6e6e73;
  --am-head: #f2f2f4;
  --am-stripe: #f7f7f9;
  --am-hover: #ececed;
  --am-graph: #1eaa4b;
  --am-graph-soft: rgba(30, 170, 75, 0.14);
  --am-grid: rgba(0, 0, 0, 0.08);
}

/* Homebrew keeps its phosphor: the graph is the same green as everything else. */
:root[data-theme="homebrew"] .activity-window {
  --am-chrome: #0a0f0a;
  --am-body: #050805;
  --am-line: #16401f;
  --am-text: #7dff9b;
  --am-muted: #3f8f52;
  --am-head: #0a140c;
  --am-stripe: #070c08;
  --am-hover: #0e1c10;
  --am-graph: #45ff74;
  --am-graph-soft: rgba(69, 255, 116, 0.14);
  --am-grid: rgba(69, 255, 116, 0.12);
  font-family: inherit;
}

.activity-window > * { min-width: 0; }

.activity-window.is-closed,
.activity-window.is-hidden { display: none; }

.am-toolbar {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center;
  gap: 16px;
  padding: 0 14px;
  border-bottom: 1px solid var(--am-line);
  background: var(--am-chrome);
  touch-action: none;
}

.am-title {
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
}

/* The segmented control. One border, dividers drawn by the buttons. */
.am-tabs {
  justify-self: center;
  display: flex;
  overflow: hidden;
  border: 1px solid var(--am-line);
  border-radius: 6px;
}

.am-tabs button {
  padding: 4px 13px;
  border: 0;
  border-left: 1px solid var(--am-line);
  background: transparent;
  color: var(--am-text);
  font: inherit;
  font-size: 11.5px;
  cursor: pointer;
}

.am-tabs button:first-child { border-left: 0; }
.am-tabs button:hover { background: var(--am-hover); }

.am-tabs button.is-on {
  background: var(--sel);
  color: #fff;
}

.am-body {
  display: grid;
  grid-template-rows: 22px minmax(0, 1fr);
  min-height: 0;
  overflow: hidden;
}

.am-head,
.am-row {
  display: grid;
  grid-template-columns: var(--am-cols, minmax(0, 1fr));
  align-items: center;
  gap: 10px;
  padding: 0 12px;
}

.am-head {
  border-bottom: 1px solid var(--am-line);
  background: var(--am-head);
  color: var(--am-muted);
  font-size: 10.5px;
}

.am-head button {
  display: flex;
  align-items: center;
  gap: 3px;
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  font: inherit;
  cursor: pointer;
  white-space: nowrap;
}

.am-head button.is-num { justify-content: flex-end; }
.am-head button:hover { color: var(--am-text); }
.am-head .am-sort { font-size: 8px; }

.am-rows {
  overflow: auto;
  min-height: 0;
}

.am-row {
  height: 21px;
  border-bottom: 1px solid transparent;
}

.am-row:nth-child(even) { background: var(--am-stripe); }
.am-row:hover { background: var(--am-hover); }

.am-row span {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* Numbers line up on the right and never reflow as digits change width. */
.am-row .am-num {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.am-row .am-name {
  display: flex;
  align-items: center;
  gap: 7px;
  font-weight: 500;
}

.am-row .am-name img,
.am-row .am-name svg { flex: none; }

.am-row.is-idle { color: var(--am-muted); }
.am-empty {
  padding: 14px 12px;
  color: var(--am-muted);
}

.am-foot {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 18px;
  align-items: center;
  padding: 10px 14px 12px;
  border-top: 1px solid var(--am-line);
  background: var(--am-chrome);
}

.am-stats {
  display: grid;
  /* Wide enough that "Data Received" and "Time Remaining" stay whole — at
     96px the labels ellipsized into "Data Recei…". */
  grid-template-columns: repeat(auto-fit, minmax(132px, 1fr));
  gap: 4px 18px;
  margin: 0;
}

.am-stats div {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  min-width: 0;
}

.am-stats dt {
  color: var(--am-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.am-stats dd {
  margin: 0;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.am-chart {
  margin: 0;
  display: grid;
  gap: 4px;
  justify-items: center;
}

.am-chart canvas {
  width: 180px;
  height: 48px;
  border: 1px solid var(--am-line);
  border-radius: 4px;
  background: var(--am-body);
}

.am-chart figcaption {
  color: var(--am-muted);
  font-size: 10.5px;
}

/* The dock tile: icon by default, live graph once the app is running. */
.am-mark {
  position: relative;
  width: 42px;
  height: 42px;
}

.am-icon {
  display: block;
  width: 100%;
  height: 100%;
}

.am-dock-graph {
  position: absolute;
  inset: 0;
  display: none;
  width: 100%;
  height: 100%;
  border-radius: 12px;
}

.finder-tool {
  display: grid;
  place-items: center;
  width: 26px;
  height: 22px;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: inherit;
  cursor: pointer;
}

.finder-tool:hover { background: var(--glass-hover); }
.finder-tool svg { width: 15px; height: 15px; display: block; }

/* One button, whichever glyph describes the view you would switch to. */
.finder-tool .view-icons,
.finder-list.is-icons ~ * .finder-tool .view-list { display: none; }

.finder-find { display: flex; align-items: center; gap: 4px; }

.finder-find input {
  width: 130px;
  padding: 3px 8px;
  border: 1px solid var(--line-strong);
  border-radius: 11px;
  background: var(--raised);
  color: var(--text);
  font-family: var(--ui-font);
  font-size: 12px;
}

.finder-find input:focus { outline: 0; border-color: var(--accent); }
.finder-find input[hidden] { display: none; }

.finder-empty {
  margin: 0;
  padding: 26px 14px;
  color: var(--muted);
  font-family: var(--ui-font);
  font-size: 13px;
  text-align: center;
}

/* Icon view: the same items as tiles instead of rows. */
.finder-list.is-icons {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(104px, 1fr));
  gap: 10px;
  padding: 14px;
  align-content: start;
}

.finder-list.is-icons .finder-row {
  display: grid;
  justify-items: center;
  gap: 6px;
  height: auto;
  padding: 10px 6px;
  border-radius: 8px;
  text-align: center;
}

.finder-list.is-icons .finder-row .name {
  display: grid;
  justify-items: center;
  gap: 6px;
  font-size: 12px;
}

.finder-list.is-icons .finder-row .name img,
.finder-list.is-icons .finder-row .name > span:first-child { width: 34px; height: 34px; font-size: 26px; }
.finder-list.is-icons .kind,
.finder-list.is-icons .where { display: none; }

.finder-toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 12px;
  border-bottom: 1px solid var(--fdr-line);
  background: var(--fdr-chrome);
}

.finder-toolbar strong {
  font-size: 13px;
  font-weight: 600;
}

.finder-arrows,
.finder-glyphs {
  display: flex;
  align-items: center;
  gap: 4px;
}

.finder-glyphs { margin-left: auto; color: var(--fdr-muted); }
.finder-glyphs svg { width: 17px; height: 17px; }

.finder-arrows button {
  width: 24px;
  height: 22px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 5px;
  background: transparent;
  color: var(--fdr-text);
  cursor: pointer;
}

.finder-arrows button:hover:not(:disabled) { background: #3a3a3d; }
.finder-arrows button:disabled { color: var(--fdr-dim); cursor: default; }
.finder-arrows svg { width: 17px; height: 17px; }

.finder-body {
  display: grid;
  grid-template-columns: 12.5rem minmax(0, 1fr);
  min-height: 0;
}

.finder-sidebar {
  padding: 10px 8px;
  overflow-y: auto;
  border-right: 1px solid var(--fdr-line);
  background: var(--fdr-side);
}

.finder-sidebar h3 {
  margin: 10px 0 4px;
  padding: 0 8px;
  color: var(--fdr-muted);
  font-size: 11px;
  font-weight: 600;
  letter-spacing: 0.02em;
}

.finder-sidebar button {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 5px 8px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--fdr-text);
  font-family: var(--ui-font);
  font-size: 12.5px;
  text-align: left;
  cursor: pointer;
}

.finder-sidebar button:hover { background: var(--fdr-side-hover); }
.finder-sidebar button.is-current { background: var(--sel); color: var(--sel-ink); }
.finder-sidebar .glyph { width: 15px; text-align: center; color: var(--fdr-accent); }
.finder-sidebar button.is-current .glyph { color: var(--sel-ink); }

.finder-main {
  display: grid;
  grid-template-rows: 26px minmax(0, 1fr);
  min-height: 0;
}

.finder-head,
.finder-row {
  display: grid;
  grid-template-columns: minmax(9rem, 1fr) 8rem minmax(6rem, 12rem);
  gap: 12px;
  align-items: center;
  padding: 0 12px;
}

.finder-head {
  border-bottom: 1px solid var(--fdr-line);
  background: var(--fdr-head);
  color: var(--fdr-muted);
  font-size: 11px;
}

.finder-list { overflow-y: auto; }

.finder-row {
  width: 100%;
  height: 26px;
  border: 0;
  background: transparent;
  color: var(--fdr-text);
  font-family: var(--ui-font);
  font-size: 12.5px;
  text-align: left;
  white-space: nowrap;
  cursor: default;
}

.finder-row:nth-child(even) { background: var(--fdr-stripe); }
.finder-row:hover { background: var(--fdr-hover); }

.finder-row.is-selected,
.finder-row:focus-visible {
  background: var(--sel);
  color: #fff;
  outline: 0;
}

.finder-row span {
  overflow: hidden;
  text-overflow: ellipsis;
}

.finder-row .name {
  display: flex;
  align-items: center;
  gap: 7px;
}

.finder-row .name img {
  width: 15px;
  height: 15px;
  border-radius: 3px;
  object-fit: contain;
}

.finder-row .kind,
.finder-row .where { color: var(--fdr-muted); }
.finder-row.is-selected .kind,
.finder-row.is-selected .where { color: color-mix(in srgb, var(--sel-ink) 82%, transparent); }

.finder-status {
  display: flex;
  align-items: center;
  justify-content: center;
  border-top: 1px solid var(--fdr-line);
  background: var(--fdr-chrome);
  color: var(--fdr-muted);
  font-size: 11px;
}

.finder-mark img,
.app-mark img { width: 100%; height: 100%; display: block; }

/* ---------------------------------------------------------------- Krome ---
   A browser window that loads the three real sites. Its own palette, because
   nothing about Chrome looks like the terminal it sits on top of. */

.krome-window {
  --k-frame: #202124;
  --k-chrome: #35363a;
  --k-hover: #3c4043;
  --k-text: #e8eaed;
  --k-muted: #9aa0a6;
  position: fixed;
  z-index: 60;
  inset: 0;
  min-height: 0;
  display: grid;
  /* minmax(0, 1fr), not 1fr: an auto-sized track takes its minimum from the
     widest row, and one long bookmarks bar would push the whole window — and
     the page framed below it — off the side of a phone. */
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: 40px 40px 30px minmax(0, 1fr);
  overflow: hidden;
  background: var(--k-frame);
  color: var(--k-text);
  font-family: var(--ui-font);
  font-size: 12px;
}

.krome-window > * { min-width: 0; }

.krome-window.is-closed,
.krome-window.is-hidden { display: none; }

.krome-window button { cursor: pointer; }

.krome-window :focus-visible {
  outline: 2px solid #8ab4f8;
  outline-offset: -2px;
}

/* Tab strip */
.krome-tabstrip {
  display: flex;
  align-items: flex-end;
  gap: 0;
  padding: 0 8px;
  background: var(--k-frame);
}

.krome-tabstrip .window-controls {
  align-self: center;
  margin: 0 12px 0 2px;
}

.krome-tabs {
  /* Only as wide as its tabs, so "+" stays beside the last one — but still
     shrinkable, so a crowded strip squeezes the tabs instead of overflowing.
     Past the point where they cannot shrink further, the strip scrolls rather
     than hiding the tabs at the end. */
  flex: 0 1 auto;
  min-width: 0;
  display: flex;
  align-items: flex-end;
  overflow-x: auto;
  overflow-y: hidden;
  scroll-behavior: smooth;
  scrollbar-width: none;
}

.krome-tabs::-webkit-scrollbar { display: none; }

/* Tabs give up width before the strip does, the way Chrome's do. */
.krome-tab {
  position: relative;
  flex: 0 1 220px;
  min-width: 40px;
  height: 34px;
  /* A tab is dragged to reorder it, so its title must not be selectable text —
     otherwise the browser starts a selection and cancels the drag. */
  user-select: none;
  -webkit-user-select: none;
  touch-action: none;
  display: grid;
  grid-template-columns: 16px minmax(0, 1fr) 16px;
  align-items: center;
  gap: 8px;
  padding: 0 8px;
  border: 0;
  border-radius: 9px 9px 0 0;
  background: transparent;
  color: var(--k-muted);
  font-size: 12px;
  text-align: left;
  /* Tabs displaced by a drag slide to their new place; the one under the
     pointer opts out below so it tracks the cursor with no lag. */
  transition: transform 160ms cubic-bezier(0.32, 0.72, 0, 1);
}

.krome-tab:hover { background: #292a2d; }

.krome-tab.is-dragging {
  z-index: 3;
  /* An inactive tab is transparent, so without a background of its own the
     lift shadow would have nothing to sit on and the tab would read as loose
     text sliding over its neighbours. The .is-active rule below still wins for
     a tab that was already the current one. */
  background: #35363a;
  color: var(--k-text);
  box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
  cursor: grabbing;
  transition: none;
}

.krome-tab.is-active {
  background: var(--k-chrome);
  color: var(--k-text);
}

/* The two curved skirts that tuck an active Chrome tab into the toolbar. */
.krome-tab.is-active::before,
.krome-tab.is-active::after {
  content: "";
  position: absolute;
  bottom: 0;
  width: 10px;
  height: 10px;
  background: var(--k-chrome);
}

.krome-tab.is-active::before {
  left: -10px;
  -webkit-mask: radial-gradient(circle 10px at 0 0, transparent 99%, #000 100%);
  mask: radial-gradient(circle 10px at 0 0, transparent 99%, #000 100%);
}

.krome-tab.is-active::after {
  right: -10px;
  -webkit-mask: radial-gradient(circle 10px at 100% 0, transparent 99%, #000 100%);
  mask: radial-gradient(circle 10px at 100% 0, transparent 99%, #000 100%);
}

.krome-tab-label {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.krome-tab-close {
  width: 16px;
  height: 16px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--k-muted);
  font-size: 13px;
  line-height: 1;
}

.krome-tab-close:hover { background: #5f6368; color: #fff; }

.krome-newtab {
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  margin: 0 0 3px 6px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--k-muted);
}

.krome-newtab:hover { background: #292a2d; }
.krome-newtab svg { width: 16px; height: 16px; }

/* Tab favicons: the page's own icon when it reports one, a letter tile when
   it does not. */
.fav {
  width: 16px;
  height: 16px;
  display: grid;
  place-items: center;
  border-radius: 4px;
  background: #5f6368;
  color: #fff;
  font-size: 9px;
  font-style: normal;
  font-weight: 700;
}

.fav img {
  width: 16px;
  height: 16px;
  border-radius: 3px;
  object-fit: contain;
}

/* A real favicon sits on its own; the letter underneath is only what shows if
   the image fails, so the tile drops its color once an icon is in place. */
.fav.has-icon {
  position: relative;
  background: transparent;
  color: transparent;
}

.fav.has-icon img {
  position: absolute;
  inset: 0;
  margin: auto;
}

.fav-daem { background: linear-gradient(180deg, #7c4dff, #3b1a80); }
.fav-mp { background: linear-gradient(180deg, #46a7ff, #0f5ab5); }
.fav-ca { background: linear-gradient(180deg, #2fd6a6, #0a7256); }
.fav-uc { background: linear-gradient(180deg, #b6e94b, #4a7a10); color: #16210a; }
.fav-gh { background: #f0f2f5; color: #14181d; }
.fav-go { background: #fff; color: #4285f4; }
.fav-any { background: linear-gradient(180deg, #6b7280, #374151); }

/* Toolbar */
.krome-toolbar {
  display: flex;
  align-items: center;
  gap: 2px;
  padding: 0 8px;
  background: var(--k-chrome);
}

.krome-icon {
  flex: none;
  width: 28px;
  height: 28px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--k-text);
}

.krome-icon svg { width: 16px; height: 16px; }
button.krome-icon:hover { background: var(--k-hover); }

button.krome-icon:disabled {
  color: #5f6368;
  cursor: default;
}

.krome-omnibox {
  flex: 1;
  min-width: 0;
  height: 28px;
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0 6px;
  padding: 0 12px;
  border-radius: 999px;
  background: var(--k-frame);
}

.krome-omnibox:focus-within { background: #17181a; box-shadow: 0 0 0 1px #8ab4f8; }

.krome-lock,
.krome-star {
  flex: none;
  display: grid;
  color: var(--k-muted);
}

.krome-lock svg,
.krome-star svg { width: 14px; height: 14px; }

.krome-omnibox input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--k-text);
  font-family: var(--ui-font);
  font-size: 12.5px;
  outline: 0;
}

.krome-omnibox input::placeholder { color: #757a80; }

.krome-avatar {
  flex: none;
  width: 22px;
  height: 22px;
  display: grid;
  place-items: center;
  margin: 0 4px;
  border-radius: 50%;
  background: #8ab4f8;
  color: #202124;
  font-size: 11px;
  font-weight: 700;
}

/* Bookmarks bar */
.krome-bookmarks {
  display: flex;
  align-items: center;
  gap: 4px;
  padding: 0 10px;
  overflow-x: auto;
  border-bottom: 1px solid #3f4043;
  background: var(--k-chrome);
  scrollbar-width: none;
}

.krome-bookmarks::-webkit-scrollbar { display: none; }

.krome-bookmark {
  flex: none;
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--k-text);
  font-family: var(--ui-font);
  font-size: 12px;
}

.krome-bookmark:hover { background: var(--k-hover); }

/* Dark Reader: the whole page is inverted and hue-rotated at the frame, which
   is the one thing that works on a cross-origin page too. Proxied pages get
   their images inverted back by the bridge; directly framed ones cannot. */
.krome-page.dr-on iframe {
  filter: var(--dr-filter, none);
}

.krome-darkreader.is-on { color: #ffd166; }

.krome-ext-popup {
  position: absolute;
  z-index: 40;
  top: 78px;
  right: 12px;
  width: 16.5rem;
  padding: 12px;
  border: 1px solid #4a4d51;
  border-radius: 10px;
  background: #292a2d;
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.55);
}

.krome-ext-popup[hidden] { display: none; }

.krome-ext-popup header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
}

.krome-ext-popup header b { font-size: 13px; }
.dr-version { margin-left: auto; color: var(--k-muted); font-size: 11px; }

.dr-mark {
  width: 16px;
  height: 16px;
  border: 1.5px solid #ffd166;
  border-radius: 50%;
  background: linear-gradient(90deg, transparent 50%, #ffd166 50%);
}

.dr-power {
  width: 100%;
  padding: 9px;
  border: 1px solid #4a4d51;
  border-radius: 7px;
  background: #35363a;
  color: var(--k-text);
  font-family: var(--ui-font);
  font-size: 13px;
  font-weight: 600;
}

.dr-power[aria-pressed="true"] {
  border-color: #ffd166;
  background: #4a3f21;
  color: #ffd166;
}

.dr-sliders {
  display: grid;
  gap: 8px;
  margin: 12px 0 6px;
}

.dr-sliders label {
  display: grid;
  grid-template-columns: 4.6rem 1fr 2.4rem;
  align-items: center;
  gap: 8px;
  color: var(--k-muted);
  font-size: 11.5px;
}

.dr-sliders output { text-align: right; }

.dr-sliders input[type="range"] {
  width: 100%;
  height: 3px;
  appearance: none;
  border-radius: 2px;
  background: #4a4d51;
}

.dr-sliders input[type="range"]::-webkit-slider-thumb {
  width: 12px;
  height: 12px;
  appearance: none;
  border-radius: 50%;
  background: #ffd166;
  cursor: pointer;
}

.dr-sliders input[type="range"]::-moz-range-thumb {
  width: 12px;
  height: 12px;
  border: 0;
  border-radius: 50%;
  background: #ffd166;
  cursor: pointer;
}

.dr-site {
  margin: 0;
  padding-top: 9px;
  border-top: 1px solid #3f4043;
  color: var(--k-muted);
  font-size: 11.5px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Viewport */
.krome-viewport {
  position: relative;
  min-height: 0;
  background: #fff;
}

.krome-page {
  position: absolute;
  inset: 0;
  overflow: auto;
}

.krome-page[hidden] { display: none; }

.krome-page iframe {
  width: 100%;
  height: 100%;
  border: 0;
  background: #fff;
}

/* Chrome's own pages: the new tab page and the failure page. */
.krome-logo {
  /* Favicon-sized by default — as a stretchable grid item in the tab strip it
     would otherwise take the full height of the tab. The dock and the new tab
     page set their own larger sizes. */
  flex: none;
  align-self: center;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 50% 50%, #4285f4 0 26%, #fff 27% 32%, transparent 33%),
    conic-gradient(from -30deg, #ea4335 0deg 120deg, #fbbc05 120deg 240deg, #34a853 240deg 360deg);
  box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1);
}

.krome-newtab-page {
  height: 100%;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 26px;
  padding: 24px;
  background: #202124;
  color: #e8eaed;
}

.krome-newtab-page .mark {
  width: 76px;
  height: 76px;
}

.krome-newtab-page .fakebar input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: #e8eaed;
  font-family: var(--ui-font);
  font-size: 13px;
  outline: 0;
}

.krome-newtab-page .fakebar input::placeholder { color: #9aa0a6; }

.krome-newtab-page .fakebar {
  width: min(460px, 90%);
  height: 44px;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 18px;
  border-radius: 999px;
  background: #303134;
  color: #9aa0a6;
  font-size: 13px;
}

.krome-shortcuts {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
}

.krome-shortcut {
  width: 106px;
  display: grid;
  justify-items: center;
  gap: 8px;
  padding: 14px 6px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: #e8eaed;
  font-family: var(--ui-font);
  font-size: 12px;
}

.krome-shortcut:hover { background: #ffffff14; }

.krome-shortcut .fav {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  font-size: 17px;
}

.krome-shortcut .fav img { width: 24px; height: 24px; }

.krome-errorpage {
  height: 100%;
  display: grid;
  align-content: center;
  gap: 14px;
  padding: 8vh clamp(24px, 12%, 140px);
  background: #202124;
  color: #9aa0a6;
  font-size: 14px;
  line-height: 1.6;
}

.krome-errorpage .glyph {
  width: 72px;
  height: 72px;
  display: grid;
  place-items: center;
  border-radius: 14px;
  background: #3c4043;
  color: #bdc1c6;
  font-size: 34px;
}

.krome-errorpage h2 {
  margin: 0;
  color: #e8eaed;
  font-size: 20px;
  font-weight: 400;
}

.krome-errorpage code {
  color: #80868b;
  font-family: var(--ui-font);
  font-size: 12px;
  letter-spacing: 0.04em;
}

.krome-errorpage button {
  justify-self: start;
  margin-top: 8px;
  padding: 8px 16px;
  border: 0;
  border-radius: 4px;
  background: #8ab4f8;
  color: #202124;
  font-family: var(--ui-font);
  font-size: 13px;
  font-weight: 500;
}

/* Loading: Chrome swaps the favicon for a spinner. */
.krome-spinner {
  width: 14px;
  height: 14px;
  border: 2px solid #5f6368;
  border-top-color: #8ab4f8;
  border-radius: 50%;
  animation: krome-spin 700ms linear infinite;
}

@keyframes krome-spin { to { transform: rotate(360deg); } }

/* On a phone the toolbar has room for navigation and the address, and nothing
   else — the decorative controls go, like they do in Chrome for Android. */
@media (max-width: 560px) {
  .krome-puzzle,
  .krome-avatar,
  .krome-dots,
  .krome-star { display: none; }

  .krome-toolbar { padding: 0 6px; }
  .krome-omnibox { margin: 0 4px; }
  .krome-tabstrip { padding: 0 6px; }
  .krome-tabstrip .window-controls { margin: 0 10px 0 0; }
  .krome-bookmarks { padding: 0 6px; }
}

@media (min-width: 901px) {
  body { background: #0d1620; }

  .mac-desktop {
    position: relative;
    min-height: 100vh;
    min-height: 100dvh;
    background: var(--wallpaper);
  }

  /* Desktop menu bar: flush to the top edge, 24px tall like the real one. */
  .mac-menubar {
    position: fixed;
    z-index: 30;
    top: 0;
    left: 0;
    right: 0;
    height: var(--menubar-h);
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 0 12px;
    background: var(--menubar-bg);
    color: var(--menubar-text);
    font-family: var(--ui-font);
    font-size: 13px;
    text-shadow: 0 0 6px rgba(0, 0, 0, 0.35);
    backdrop-filter: saturate(180%) blur(20px);
  }

  .mac-menu-left,
  .mac-menu-right {
    display: flex;
    align-items: center;
    gap: 2px;
  }

  .mac-menu-right { gap: 12px; }

  .menu-glyph svg { width: 17px; height: 15px; display: block; }

  .menu-search {
    height: var(--menubar-h);
    display: flex;
    align-items: center;
    padding: 0 6px;
    border: 0;
    border-radius: 4px;
    background: transparent;
    color: inherit;
    cursor: default;
  }

  /* The clock opens Notification Center, so it has to look pressable. */
  #menu-clock {
    padding: 2px 6px;
    border-radius: 4px;
    cursor: default;
  }

  #menu-clock:hover { background: var(--glass-hover); }
  #menu-clock.is-on { background: var(--glass-active); color: #fff; }

  .menu-fullscreen {
    height: var(--menubar-h);
    display: flex;
    align-items: center;
    padding: 0 6px;
    border: 0;
    border-radius: 4px;
    background: transparent;
    color: inherit;
    cursor: default;
  }

  .menu-fullscreen:hover { background: var(--glass-hover); }
  .menu-fullscreen svg { width: 15px; height: 15px; display: block; }

  /* One button, two glyphs — whichever matches what the click will do. */
  .menu-fullscreen .fs-out,
  :fullscreen .menu-fullscreen .fs-in { display: none; }
  :fullscreen .menu-fullscreen .fs-out { display: block; }

  .menu-search:hover { background: var(--glass-hover); }
  .menu-search.is-on { background: var(--glass-active); color: #fff; }
  .menu-search svg { width: 16px; height: 16px; display: block; }

  /* Menu bar: a title opens a menu on click, and once one is open, moving
     across the bar switches between them the way the real one does. */
  .mac-menu { position: relative; }

  .mac-menu-title {
    height: var(--menubar-h);
    display: flex;
    align-items: center;
    padding: 0 10px;
    border: 0;
    border-radius: 4px;
    background: transparent;
    color: inherit;
    font-family: var(--ui-font);
    font-size: 13px;
    line-height: 1;
    cursor: default;
  }

  .mac-menu-title.is-app { font-weight: 600; }

  .mac-menu-title.mac-mark { padding: 0 11px; }
  .mac-mark svg { width: 14px; height: 16px; display: block; }

  .mac-menu-title:hover { background: var(--glass-hover); }

  .mac-menu-title[aria-expanded="true"] {
    background: var(--glass-active);
    color: #fff;
  }

  .mac-dropdown {
    position: absolute;
    z-index: 50;
    top: calc(var(--menubar-h) - 1px);
    left: 0;
    min-width: 15rem;
    padding: 5px;
    border: 1px solid var(--glass-line);
    border-radius: 9px;
    /* Nearly opaque on purpose: the menu bar above is itself a backdrop root,
       so a child's backdrop-filter has nothing of the page to blur and the
       panel would just be see-through. */
    background: var(--glass);
    box-shadow: 0 14px 40px rgba(0, 0, 0, 0.5);
  }

  .mac-dropdown[hidden] { display: none; }

  .mac-dropdown button {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 2rem;
    padding: 4px 9px;
    border: 0;
    border-radius: 5px;
    background: transparent;
    color: var(--glass-text);
    font-family: var(--ui-font);
    font-size: 13px;
    text-align: left;
    white-space: nowrap;
    cursor: default;
  }

  .mac-dropdown button em {
    color: var(--glass-muted);
    font-style: normal;
  }

  .mac-dropdown button:hover,
  .mac-dropdown button:focus-visible {
    background: var(--sel);
    color: #fff;
    outline: 0;
  }

  .mac-dropdown button:hover em,
  .mac-dropdown button:focus-visible em { color: rgba(255, 255, 255, 0.75); }

  .mac-dropdown hr {
    height: 1px;
    margin: 5px 9px;
    border: 0;
    background: var(--glass-line);
  }

  /* Right-click menu: the same panel as the menu bar's, placed at the pointer.
     Position comes from inline styles set when it opens. */
  .mac-contextmenu {
    position: fixed;
    z-index: 200;
    top: auto;
    left: auto;
    min-width: 13rem;
  }

  .mac-dropdown button:disabled {
    color: var(--glass-dim);
    background: transparent;
  }

  /* Wallpapers, cycled from the desktop's own context menu. */
  .mac-desktop.wallpaper-2 {
    background:
      radial-gradient(120% 90% at 20% 10%, rgba(196, 122, 92, 0.5), transparent 60%),
      radial-gradient(90% 80% at 85% 90%, rgba(90, 54, 96, 0.55), transparent 62%),
      linear-gradient(170deg, #3a2438 0%, #241a2c 55%, #140f1c 100%);
  }

  .mac-desktop.wallpaper-3 {
    background:
      radial-gradient(110% 90% at 70% 15%, rgba(58, 132, 128, 0.45), transparent 62%),
      radial-gradient(90% 80% at 10% 90%, rgba(22, 62, 78, 0.6), transparent 65%),
      linear-gradient(175deg, #16333a 0%, #0f242c 55%, #08151b 100%);
  }

  .mac-desktop.wallpaper-4 {
    background:
      radial-gradient(120% 90% at 50% 0%, rgba(120, 120, 130, 0.35), transparent 60%),
      linear-gradient(180deg, #2a2d33 0%, #191b1f 55%, #0d0e11 100%);
  }

  .app-window {
    position: fixed;
    z-index: 5;
    top: calc(var(--menubar-h) + 10px);
    right: 24px;
    bottom: calc(var(--dock-h) + 12px);
    left: 24px;
    /* A terminal is a terminal — roughly 130 columns of this 13px mono, which
       is where a real one gets dragged to. Past that it stops growing and the
       auto margins center it in the space instead of spanning the desktop.
       The height cap matters just as much: capping width alone leaves a
       portrait window on a tall display, which no one ever sizes a terminal to. */
    max-width: 1100px;
    max-height: 700px;
    margin: auto;
    min-height: 0;
    display: grid;
    grid-template-rows: 38px minmax(0, 1fr) 22px;
    overflow: hidden;
    border: 1px solid rgba(255, 255, 255, 0.16);
    border-radius: 10px;
    background: #000;
    /* A contact shadow only. The old 60px ambient blur threw a halo across the
       wallpaper, which read as the desktop dimming whenever a window opened. */
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.5);
    transform-origin: bottom center;
    transition:
      top 260ms cubic-bezier(0.32, 0.72, 0, 1),
      right 260ms cubic-bezier(0.32, 0.72, 0, 1),
      bottom 260ms cubic-bezier(0.32, 0.72, 0, 1),
      left 260ms cubic-bezier(0.32, 0.72, 0, 1),
      width 260ms cubic-bezier(0.32, 0.72, 0, 1),
      height 260ms cubic-bezier(0.32, 0.72, 0, 1),
      border-radius 260ms ease,
      transform 260ms cubic-bezier(0.4, 0, 0.2, 1),
      opacity 200ms ease;
  }

  /* Zoom fills the usable desktop: below the menu bar, above the dock. */
  .app-window.is-zoomed {
    top: var(--menubar-h);
    right: 0;
    bottom: var(--dock-h);
    left: 0;
    max-width: none;
    max-height: none;
    border-radius: 0;
    border-color: transparent;
  }

  .app-window.is-hidden {
    opacity: 0;
    pointer-events: none;
    transform: translate3d(0, 45vh, 0) scale(0.08);
  }

  /* Closing has to actually put the window away — on its own, the shrink just
     left a smaller window sitting there. It stays in the layer so the dock can
     bring it back; `inert` and aria-hidden are set alongside this in script.js. */
  .app-window.is-closed {
    opacity: 0;
    pointer-events: none;
    transform: scale(0.92);
    transition-duration: 160ms;
  }

  /* Krome is a second window on the same desktop: offset from the terminal,
     raised above it whenever it is the one you clicked last. */
  .krome-window {
    z-index: 12;
    top: calc(var(--menubar-h) + 30px);
    right: 58px;
    bottom: calc(var(--dock-h) + 34px);
    left: 108px;
    /* Slightly smaller than the terminal, and centered in a band that sits
       further right, so the two read as stacked windows rather than one. */
    max-width: 1050px;
    max-height: 665px;
    grid-template-rows: 40px 40px 30px minmax(0, 1fr);
    border-radius: 11px;
    background: var(--k-frame);
  }

  .app-window.is-front { z-index: 20; }

  /* Finder opens up and to the left of the other two. */
  .finder-window {
    z-index: 10;
    top: calc(var(--menubar-h) + 52px);
    right: 150px;
    bottom: calc(var(--dock-h) + 56px);
    left: 60px;
    max-width: 940px;
    max-height: 620px;
    grid-template-rows: 44px minmax(0, 1fr) 24px;
    border-radius: 11px;
    background: var(--fdr-body);
  }

  .finder-window.is-closed { display: none; }

  .finder-window.is-hidden {
    display: grid;
    opacity: 0;
    pointer-events: none;
    transform: translate3d(0, 45vh, 0) scale(0.08);
  }

  /* Activity Monitor opens toward the lower right, clear of the other three. */
  .activity-window {
    z-index: 14;
    top: calc(var(--menubar-h) + 96px);
    right: 70px;
    bottom: calc(var(--dock-h) + 26px);
    left: 210px;
    max-width: 860px;
    max-height: 560px;
    grid-template-rows: 52px minmax(0, 1fr) auto;
    border-radius: 11px;
    background: var(--am-body);
  }

  .activity-window.is-closed { display: none; }

  .activity-window.is-hidden {
    display: grid;
    opacity: 0;
    pointer-events: none;
    transform: translate3d(0, 45vh, 0) scale(0.08);
  }

  .am-toolbar { touch-action: none; }

  /* Once a window has been moved or resized it stops taking its box from the
     stylesheet: explicit left/top/width/height are written inline, and the
     insets, centring margins and size caps all have to get out of the way. */
  .app-window.is-free {
    right: auto;
    bottom: auto;
    margin: 0;
    max-width: none;
    max-height: none;
  }

  /* Nothing animates while the pointer is driving it. */
  .app-window.is-moving { transition: none; }

  .topbar,
  .krome-tabstrip { touch-action: none; }

  /* Grab strips just inside each edge — outside would be clipped by the
     window's own overflow. */
  .win-resize {
    display: block;
    position: absolute;
    /* Above the status bar: it carries a z-index for its fixed mobile layout,
       and as a grid item that makes it a stacking context here too. */
    z-index: 30;
  }

  /* A zoomed window is pinned to the desktop; there is nothing to drag. */
  .app-window.is-zoomed .win-resize { display: none; }

  /* The traffic lights live in the very corner the NW grip covers, and a
     resize handle must never take the close button's clicks. */
  .window-controls {
    position: relative;
    z-index: 31;
  }

  .win-resize-n,
  .win-resize-s {
    left: 14px;
    right: 14px;
    height: 6px;
    cursor: ns-resize;
  }

  .win-resize-n { top: 0; }
  .win-resize-s { bottom: 0; }

  .win-resize-e,
  .win-resize-w {
    top: 14px;
    bottom: 14px;
    width: 6px;
    cursor: ew-resize;
  }

  .win-resize-e { right: 0; }
  .win-resize-w { left: 0; }

  /* Bigger than the edges: the window's rounded corner is clipped away by its
     own overflow, so the outermost pixels cannot be hit and the grip has to
     reach further in to stay comfortably grabbable. */
  .win-resize-ne,
  .win-resize-nw,
  .win-resize-se,
  .win-resize-sw {
    width: 20px;
    height: 20px;
  }

  .win-resize-nw { top: 0; left: 0; cursor: nwse-resize; }
  .win-resize-se { right: 0; bottom: 0; cursor: nwse-resize; }
  .win-resize-ne { top: 0; right: 0; cursor: nesw-resize; }
  .win-resize-sw { bottom: 0; left: 0; cursor: nesw-resize; }

  /* A drag that crosses a framed page would otherwise be swallowed by it. */
  .is-window-dragging { user-select: none; }
  .is-window-dragging iframe { pointer-events: none; }

  /* The first click away from a context menu dismisses it, including over a
     cross-origin Krome page whose pointer events cannot bubble to the desktop. */
  .is-context-menu-open iframe { pointer-events: none; }

  /* Drag on the desktop and you get a selection rectangle, drawn on the
     desktop layer so windows stay above it. */
  .desktop-marquee {
    position: fixed;
    z-index: 3;
    overflow: hidden;
    /* Mixed from the theme's accent rather than a fixed amber, so every
       appearance draws its own rectangle — and a future theme gets one free. */
    border: 1px solid color-mix(in srgb, var(--accent) 55%, transparent);
    background: color-mix(in srgb, var(--accent) 10%, transparent);
    pointer-events: none;
  }

  /* Marked in the corners rather than the middle, at a fixed small size. The
     corner under the cursor is left bare — the pointer is always at one corner
     of the rectangle you are drawing. */
  .marquee-mark {
    position: absolute;
    /* The theme's ink, not white — on a light marquee white at 3% is nothing
       at all, so the easter egg only existed in one appearance. */
    color: var(--text);
    font-size: 10px;
    letter-spacing: 0.04em;
    line-height: 1;
    opacity: 0.03;
    white-space: nowrap;
  }

  .marquee-mark[data-corner="tl"] { top: 4px; left: 5px; }
  .marquee-mark[data-corner="tr"] { top: 4px; right: 5px; }
  .marquee-mark[data-corner="bl"] { bottom: 4px; left: 5px; }
  .marquee-mark[data-corner="br"] { bottom: 4px; right: 5px; }

  .desktop-marquee[data-pointer="tl"] .marquee-mark[data-corner="tl"],
  .desktop-marquee[data-pointer="tr"] .marquee-mark[data-corner="tr"],
  .desktop-marquee[data-pointer="bl"] .marquee-mark[data-corner="bl"],
  .desktop-marquee[data-pointer="br"] .marquee-mark[data-corner="br"] { display: none; }

  /* The half a window will take if you let go here. */
  .snap-preview {
    position: fixed;
    z-index: 25;
    border: 1px solid rgba(255, 255, 255, 0.55);
    border-radius: 11px;
    background: rgba(220, 232, 245, 0.18);
    box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
    opacity: 0;
    pointer-events: none;
    backdrop-filter: blur(3px);
    transition:
      opacity 120ms ease,
      left 150ms cubic-bezier(0.32, 0.72, 0, 1),
      width 150ms cubic-bezier(0.32, 0.72, 0, 1);
  }

  .snap-preview.is-visible { opacity: 1; }

  .krome-window.is-closed { display: none; }

  .krome-window.is-hidden {
    display: grid;
    opacity: 0;
    pointer-events: none;
    transform: translate3d(0, 45vh, 0) scale(0.08);
  }

  .app-window .topbar {
    height: auto;
    padding-inline: 12px;
    border-bottom: 1px solid var(--line-strong);
  }

  .app-window .workspace { height: auto; }

  .app-window .statusbar {
    position: static;
    height: auto;
  }

  /* Dock */
  .mac-dock {
    position: fixed;
    z-index: 40;
    bottom: 6px;
    left: 50%;
    display: flex;
    align-items: flex-end;
    /* Each tile carries 5px of transparent padding of its own, so the gap you
       see between two icons is this plus 10. Kept small for that reason. */
    gap: 2px;
    /* Each tile insets its own artwork by 5px, so the margin you actually see
       above and below an icon is this plus 5. The bottom keeps a little extra
       for the running dots. */
    padding: 2px 2px 6px;
    border: 1px solid var(--glass-line);
    border-radius: 20px;
    background: var(--dock-bg);
    box-shadow:
      0 12px 34px rgba(0, 0, 0, 0.42),
      inset 0 1px 0 rgba(255, 255, 255, 0.22);
    transform: translateX(-50%);
    backdrop-filter: saturate(180%) blur(28px);
  }

  .dock-sep {
    align-self: stretch;
    width: 1px;
    /* No bottom margin: the dock's padding is 5px on top and 9px underneath,
       so an even margin here would sit the line 4px higher off the bottom edge
       than off the top. */
    margin: 4px 2px 0;
    background: var(--glass-active);
  }

  .dock-app {
    position: relative;
    width: 52px;
    height: 52px;
    display: grid;
    place-items: center;
    /* The macOS icon carries 19% transparent margin of its own; matching that
       here is what makes every tile read at the same size. */
    padding: 5px;
    border: 0;
    border-radius: 16px;
    background-clip: content-box;
    background: #2c3746;
    color: #eef2f7;
    font-family: var(--ui-font);
    font-size: 15px;
    font-weight: 700;
    letter-spacing: -0.02em;
    text-decoration: none;
    cursor: pointer;
    /* drop-shadow follows the painted tile; box-shadow would trace the full
       52px box and give away the padding. */
    box-shadow: none;
    filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.4));
    transform-origin: bottom center;
    transition: transform 140ms cubic-bezier(0.32, 0.72, 0, 1);
  }

  .dock-app > span { line-height: 1; }

  /* Terminal and Finder are the real macOS artwork, which carries its own 19%
     transparent margin — so no padding and no tile of ours underneath. */
  .dock-terminal,
  .dock-finder { padding: 0; background: none; box-shadow: none; filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.4)); }
  .dock-terminal .app-mark,
  .dock-finder .finder-mark { width: 52px; height: 52px; }

  /* Mail is macOS artwork like Finder and Terminal: its own margin, no tile. */
  .dock-mail,
  .dock-settings,
  .dock-trash { padding: 0; background: none; box-shadow: none; filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.4)); }
  .dock-mail .app-mark,
  .dock-settings .app-mark,
  .dock-trash .app-mark { width: 52px; height: 52px; }

  .dock-github { background: linear-gradient(180deg, #ffffff 0%, #cfd4da 100%); color: #14181d; font-size: 20px; }
  .dock-github svg { width: 26px; height: 26px; }

  .dock-krome { background: linear-gradient(180deg, #ffffff 0%, #e2e6ea 100%); }
  /* The ball nearly fills its tile, as it does in the real icon — 30px left far
     too much white around it inside a 42px face. */
  .dock-krome .krome-logo { width: 36px; height: 36px; }

  /* Every icon declares `background` as a shorthand, which resets
     background-clip — so the clip is restated last, after all of them. */
  .dock-app { background-clip: content-box; }
  .dock-finder,
  .dock-terminal,
  .dock-mail,
  .dock-settings,
  .dock-trash { background-clip: border-box; }

  /* Dock magnification: the hovered icon lifts, and — as in the real dock —
     its neighbours slide outwards to make room rather than being crowded into
     it. Scaling alone does not move anything: a 42px tile at 1.24 grows 5px
     towards its neighbour and the neighbour at 1.1 grows 2px back, which eats
     most of the 12px between them. The sideways nudge is what keeps them
     apart. */
  .dock-app:hover,
  .dock-app:focus-visible { transform: translateY(-9px) scale(1.24); }

  .dock-app:hover + .dock-app,
  .dock-app:focus-visible + .dock-app { transform: translate(5px, -4px) scale(1.1); }

  .dock-app:has(+ .dock-app:hover),
  .dock-app:has(+ .dock-app:focus-visible) { transform: translate(-5px, -4px) scale(1.1); }

  .dock-app:hover + .dock-app + .dock-app,
  .dock-app:focus-visible + .dock-app + .dock-app { transform: translateX(2px); }

  .dock-app:has(+ .dock-app + .dock-app:hover),
  .dock-app:has(+ .dock-app + .dock-app:focus-visible) { transform: translateX(-2px); }

  .dock-app.is-running::after {
    content: "";
    position: absolute;
    /* Rides up with the tighter dock padding — at -6px it would have sat 1px
       off the dock's bottom edge. */
    bottom: -4px;
    left: 50%;
    width: 4px;
    height: 4px;
    border-radius: 50%;
    background: rgba(255, 255, 255, 0.85);
    transform: translateX(-50%);
  }

  .dock-app small {
    position: absolute;
    bottom: calc(100% + 14px);
    display: none;
    padding: 4px 9px;
    border: 1px solid var(--glass-line);
    border-radius: 7px;
    background: rgba(30, 36, 44, 0.9);
    color: #fff;
    font-size: 12px;
    font-weight: 500;
    letter-spacing: 0;
    white-space: nowrap;
    backdrop-filter: blur(12px);
  }

  .dock-app:hover small,
  .dock-app:focus-visible small { display: block; }
}

/* ---------------------------------------------------------------- TextEdit */
.editor-layer {
  position: fixed;
  z-index: 168;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 7vh 18px;
  background: transparent;
  opacity: 0;
  transition: opacity 180ms ease;
}

.editor-layer[hidden] { display: none; }
.editor-layer.is-open { opacity: 1; }

.editor {
  width: min(600px, 100%);
  height: min(440px, 100%);
  display: grid;
  grid-template-rows: 40px minmax(0, 1fr);
  border: 1px solid var(--glass-line);
  border-radius: 12px;
  background: var(--glass);
  box-shadow: 0 30px 80px var(--shadow-strong);
  font-family: var(--ui-font);
  overflow: hidden;
  backdrop-filter: saturate(180%) blur(26px);
  transform: scale(0.98);
  transition: transform 180ms cubic-bezier(0.32, 0.72, 0, 1);
}

.editor-layer.is-open .editor { transform: none; }

.editor-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 12px;
  border-bottom: 1px solid var(--glass-hairline);
  background: var(--glass-hairline);
}

.editor-bar .is-dead { width: 12px; height: 12px; border-radius: 50%; background: var(--glass-hover); }

/* The title is the filename, editable in place as it is in TextEdit. */
.editor-name {
  /* Not flex:1 — a field that fills the bar leaves nothing to drag the window
     by, and the bar is how every other panel here is moved. */
  flex: 0 1 240px;
  min-width: 0;
  margin: 0 auto;
  border: 1px solid transparent;
  border-radius: 5px;
  padding: 3px 7px;
  background: transparent;
  color: var(--glass-text);
  font-family: inherit;
  font-size: 13px;
  font-weight: 500;
  text-align: center;
}

.editor-name:hover { border-color: var(--glass-line); }
.editor-name:focus { outline: 0; border-color: var(--accent); background: var(--glass-hover); text-align: left; }

.editor-saved {
  flex: none;
  width: 42px;
  color: var(--teal);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 10.5px;
  text-align: right;
}

.editor textarea {
  width: 100%;
  height: 100%;
  padding: 16px 18px;
  border: 0;
  background: transparent;
  color: var(--glass-text);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 13px;
  line-height: 1.6;
  resize: none;
}

.editor textarea:focus { outline: 0; }
.editor textarea::placeholder { color: var(--glass-dim); }

.ql-text {
  margin: 10px 0 0;
  max-height: 40vh;
  overflow: auto;
  color: var(--glass-text);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 12.5px;
  line-height: 1.55;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}

.ql-text.is-empty { color: var(--glass-dim); font-style: italic; }

.finder-empty-trash {
  border: 0;
  padding: 0;
  background: none;
  color: var(--accent);
  font: inherit;
  cursor: pointer;
  text-decoration: underline;
}

/* ---------------------------------------------------------------- Settings */
/* No backdrop tint on any of these. A panel opening should not dim the
   desktop behind it — the layer is transparent and exists only to catch the
   click that closes the panel. (Mission Control keeps its dim: that is a mode
   change, not a window.) */
.settings-layer {
  position: fixed;
  z-index: 165;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 6vh 18px;
  background: transparent;
  opacity: 0;
  transition: opacity 200ms ease;
}

.settings-layer[hidden] { display: none; }
.settings-layer.is-open { opacity: 1; }

.settings {
  width: min(680px, 100%);
  height: min(480px, 100%);
  display: grid;
  grid-template-rows: 40px minmax(0, 1fr);
  border: 1px solid var(--glass-line);
  border-radius: 12px;
  background: var(--glass);
  box-shadow: 0 30px 80px var(--shadow-strong);
  font-family: var(--ui-font);
  overflow: hidden;
  backdrop-filter: saturate(180%) blur(26px);
  transform: scale(0.98);
  transition: transform 200ms cubic-bezier(0.32, 0.72, 0, 1);
}

.settings-layer.is-open .settings { transform: none; }

.settings-bar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 12px;
  border-bottom: 1px solid var(--glass-hairline);
  background: var(--glass-hairline);
}

.settings-bar strong { color: var(--glass-text); font-size: 13px; font-weight: 500; }
.settings-bar .is-dead { width: 12px; height: 12px; border-radius: 50%; background: var(--glass-hover); }

.settings-body {
  display: grid;
  grid-template-columns: 168px minmax(0, 1fr);
  min-height: 0;
}

.settings-side {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 10px 8px;
  border-right: 1px solid var(--glass-hairline);
  overflow-y: auto;
}

.set-side-item {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 7px 10px;
  border: 0;
  border-radius: 7px;
  background: transparent;
  color: var(--glass-text);
  font-family: inherit;
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}

.set-side-item:hover { background: var(--glass-hover); }
.set-side-item.is-current { background: var(--sel); color: var(--sel-ink); }
.set-glyph { width: 16px; text-align: center; color: var(--accent); }
.set-side-item.is-current .set-glyph { color: var(--sel-ink); }

.settings-pane {
  padding: 18px 20px 22px;
  overflow-y: auto;
  color: var(--glass-text);
}

.settings-pane h2 { margin: 0; font-size: 17px; font-weight: 500; }
.set-note { margin: 4px 0 16px; color: var(--glass-muted); font-size: 12px; }

.theme-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
  margin-bottom: 18px;
}

.theme-card {
  display: grid;
  justify-items: center;
  gap: 5px;
  padding: 10px 6px 9px;
  border: 1px solid var(--glass-line);
  border-radius: 10px;
  background: transparent;
  color: var(--glass-text);
  font-family: inherit;
  cursor: pointer;
}

.theme-card:hover { background: var(--glass-hover); }
.theme-card.is-current { border-color: var(--sel); box-shadow: 0 0 0 2px var(--sel); }
.theme-card b { font-size: 12.5px; font-weight: 500; }
.theme-card small { color: var(--glass-muted); font-size: 10.5px; text-align: center; }

/* Each swatch paints its own theme, so the preview cannot lie about it. */
.theme-swatch {
  width: 100%;
  height: 44px;
  display: grid;
  align-content: center;
  gap: 4px;
  padding: 8px;
  border-radius: 6px;
  overflow: hidden;
}

.theme-swatch i { height: 4px; border-radius: 2px; }
.theme-swatch i:nth-child(1) { width: 70%; }
.theme-swatch i:nth-child(2) { width: 45%; }
.theme-swatch i:nth-child(3) { width: 58%; }

.theme-swatch[data-preview="light"] { background: #e9ebef; }
.theme-swatch[data-preview="light"] i { background: #23272e; }
.theme-swatch[data-preview="light"] i:nth-child(2) { background: #a5701a; }

.theme-swatch[data-preview="dark"] { background: #0b0d10; }
.theme-swatch[data-preview="dark"] i { background: #d7dce3; }
.theme-swatch[data-preview="dark"] i:nth-child(2) { background: #d8a657; }

.theme-swatch[data-preview="homebrew"] { background: #000; }
.theme-swatch[data-preview="homebrew"] i { background: #33ff33; }
.theme-swatch[data-preview="homebrew"] i:nth-child(2) { background: #4dff4d; }

.wall-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 8px;
  margin-bottom: 18px;
}

.wall-card {
  height: 52px;
  border: 1px solid var(--glass-line);
  border-radius: 8px;
  cursor: pointer;
  background: var(--wallpaper);
}

.wall-card.is-current { border-color: var(--sel); box-shadow: 0 0 0 2px var(--sel); }

.set-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 0;
  border-top: 1px solid var(--glass-hairline);
  font-size: 13px;
}

.set-button {
  padding: 4px 12px;
  border: 1px solid var(--glass-line);
  border-radius: 6px;
  background: var(--glass-hover);
  color: var(--glass-text);
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
}

.set-button:hover { background: var(--glass-active); }

.set-facts {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 6px 16px;
  margin: 14px 0 0;
  font-size: 13px;
}

.set-facts dt { color: var(--glass-muted); }
.set-facts dd { margin: 0; }

@media (max-width: 640px) {
  .settings { height: min(560px, 100%); }
  .settings-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); }
  .settings-side { flex-direction: row; border-right: 0; border-bottom: 1px solid var(--glass-hairline); }
  .theme-grid { grid-template-columns: minmax(0, 1fr); }
}

@media (prefers-reduced-motion: reduce) {
  .settings-layer, .settings { transition-duration: 1ms; }
}

/* -------------------------------------------------------------------- Mail */
.compose-layer {
  position: fixed;
  z-index: 160;
  inset: 0;
  display: grid;
  align-items: start;
  justify-items: center;
  padding: 9vh 18px 18px;
  background: transparent;
  opacity: 0;
  transition: opacity 220ms ease;
}

.compose-layer[hidden] { display: none; }
.compose-layer.is-open { opacity: 1; }

.compose {
  width: min(560px, 100%);
  display: flex;
  flex-direction: column;
  border: 1px solid var(--glass-line);
  border-radius: 12px;
  background: var(--glass);
  box-shadow: 0 30px 80px var(--shadow-strong);
  font-family: var(--ui-font);
  overflow: hidden;
  backdrop-filter: saturate(180%) blur(26px);
  transform: translateY(-10px);
  transition: transform 220ms cubic-bezier(0.32, 0.72, 0, 1);
}

.compose-layer.is-open .compose { transform: none; }

.compose-bar {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  align-items: center;
  gap: 12px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--glass-hairline);
  background: var(--glass-hover);
}

.compose-bar strong {
  color: var(--glass-text);
  font-size: 13px;
  font-weight: 500;
  text-align: center;
}

/* The two dead lights are decoration: a sheet has nothing to minimise into. */
.compose-bar .is-dead {
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: var(--glass-hover);
}

.compose-send {
  padding: 4px 14px;
  border: 0;
  border-radius: 6px;
  background: var(--sel);
  color: #fff;
  font-family: var(--ui-font);
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
}

.compose-send:hover { background: #3a78dc; }
.compose-send:disabled { opacity: 0.55; cursor: default; }

.compose-field {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 9px 14px;
  border-bottom: 1px solid var(--glass-hairline);
  font-size: 13px;
}

.compose-field > span {
  flex: none;
  width: 44px;
  color: var(--glass-muted);
}

.compose-field b { color: var(--accent); font-weight: 400; }

.compose-field input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--glass-text);
  font-family: inherit;
  font-size: 13px;
}

.compose-field input:focus { outline: 0; }
.compose-field input::placeholder { color: var(--glass-dim); }

.compose textarea {
  min-height: 190px;
  padding: 14px;
  border: 0;
  background: transparent;
  color: var(--menubar-text);
  font-family: inherit;
  font-size: 13.5px;
  line-height: 1.55;
  resize: vertical;
}

.compose textarea:focus { outline: 0; }
.compose textarea::placeholder { color: var(--glass-dim); }

/* Off-screen rather than display:none — a hidden field some bots skip, this
   one they fill in. */
.compose-trap {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  opacity: 0;
}

.compose-foot {
  padding: 9px 14px;
  border-top: 1px solid var(--glass-hairline);
  background: var(--glass-hairline);
}

.compose-foot p {
  margin: 0;
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 11px;
}

.compose-foot .is-dim { color: var(--dim); }
.compose-foot .is-ok { color: var(--teal); }
.compose-foot .is-err { color: var(--red); }

@media (prefers-reduced-motion: reduce) {
  .compose-layer,
  .compose { transition-duration: 1ms; }
}

/* ------------------------------------------------------------ Desktop files */
.desk-files { display: none; }

@media (min-width: 901px) {
  /* Top right, as macOS stacks them, and clear of the menu bar. */
  /* A layer over the whole desktop rather than a corner stack, so an icon can
     be dropped anywhere. It lets pointer events through, or it would swallow
     every click and the marquee with them. */
  .desk-files {
    /* Overrides the display:none the base rule uses to keep icons off phones. */
    display: block;
    position: fixed;
    z-index: 6;
    inset: 0;
    pointer-events: none;
  }

  .desk-file {
    position: absolute;
    width: 92px;
    pointer-events: auto;
    touch-action: none;
    display: grid;
    justify-items: center;
    gap: 4px;
    padding: 6px 4px 5px;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: #fff;
    font-family: var(--ui-font);
    cursor: default;
  }

  .desk-icon {
    width: 52px;
    height: 64px;
    display: grid;
    place-items: center;
    color: var(--accent);
    font-size: 24px;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.35);
  }

  /* A note: a sheet with a mark on it. Tokenised so a theme that is not made
     of paper does not get a white rectangle. */
  .desk-icon.is-text {
    border: 1px solid var(--doc-edge);
    border-radius: 5px;
    background: var(--doc-face);
    color: var(--muted);
    font-size: 20px;
  }

  /* macOS' own folder artwork, with the section's mark laid over it. */
  .desk-icon.is-folder {
    position: relative;
    width: 58px;
    height: 58px;
    background: none;
    border: 0;
    box-shadow: none;
    filter: drop-shadow(0 2px 5px rgba(0, 0, 0, 0.4));
  }

  .folder-art {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    display: block;
  }

  /* A blue folder on a green desktop reads as wrong, so Homebrew turns the
     artwork itself rather than swapping in a different picture. */
  :root[data-theme="homebrew"] .folder-art {
    filter: hue-rotate(-88deg) saturate(1.35) brightness(0.82);
  }

  .desk-file small {
    padding: 1px 6px;
    border-radius: 4px;
    color: var(--wall-ink);
    font-size: 11.5px;
    text-shadow: var(--wall-ink-shadow);
    white-space: nowrap;
  }

  /* macOS highlights a desktop icon with a soft rounded backing, not a hard
     ring — a square outline around a folder traces the box, not the shape. */
  .desk-file.is-selected .desk-icon::after {
    content: "";
    position: absolute;
    inset: -5px -3px;
    z-index: -1;
    border-radius: 9px;
    background: color-mix(in srgb, var(--sel) 40%, transparent);
  }

  .desk-icon { position: relative; }
  .desk-file.is-selected .desk-icon.is-text { border-color: color-mix(in srgb, var(--sel) 60%, transparent); }

  .desk-file.is-dragging {
    z-index: 2;
    opacity: 0.85;
    cursor: grabbing;
  }

  /* Only Clean Up animates. A dragged icon must track the pointer exactly. */
  .desk-file.is-tidying {
    transition: left 260ms cubic-bezier(0.32, 0.72, 0, 1),
                top 260ms cubic-bezier(0.32, 0.72, 0, 1);
  }

  .desk-file.is-selected small {
    background: var(--sel);
    color: var(--sel-ink);
    text-shadow: none;
  }
}

/* ---------------------------------------------------------------- Quick Look */
.quicklook {
  position: fixed;
  z-index: 170;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 6vh 18px;
  background: transparent;
  opacity: 0;
  transition: opacity 160ms ease;
}

.quicklook[hidden] { display: none; }
.quicklook.is-open { opacity: 1; }

.ql-panel {
  width: min(560px, 100%);
  max-height: 100%;
  margin: 0;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--glass-line);
  border-radius: 12px;
  background: var(--glass);
  box-shadow: 0 30px 80px var(--shadow-strong);
  font-family: var(--ui-font);
  overflow: hidden;
  backdrop-filter: saturate(180%) blur(26px);
  transform: scale(0.97);
  transition: transform 160ms cubic-bezier(0.32, 0.72, 0, 1);
}

.quicklook.is-open .ql-panel { transform: none; }

.ql-panel header {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--glass-hairline);
  background: var(--glass-hairline);
  color: var(--glass-text);
  font-size: 13px;
}

.ql-panel header b { flex: 1; font-weight: 500; }
.ql-glyph { color: var(--accent); font-family: "SFMono-Regular", "SF Mono", Menlo, monospace; }

.ql-panel header button {
  border: 0;
  padding: 3px 10px;
  border-radius: 6px;
  background: var(--glass-hover);
  color: var(--glass-text);
  font-family: inherit;
  font-size: 12px;
  cursor: pointer;
}

.ql-panel header button:hover { background: var(--glass-active); }
#ql-close { padding: 3px 8px; background: transparent; font-size: 15px; }

.ql-body {
  padding: 16px 18px 18px;
  overflow-y: auto;
  color: var(--glass-text);
}

.ql-title {
  margin: 0 0 10px;
  font-size: 19px;
  font-weight: 500;
}

.ql-body p {
  margin: 0 0 8px;
  color: var(--glass-muted);
  font-size: 12.5px;
  line-height: 1.5;
}

.ql-list {
  margin: 10px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 1px;
}

.ql-list li {
  display: flex;
  align-items: baseline;
  gap: 8px;
  padding: 7px 0;
  border-top: 1px solid var(--glass-hairline);
  font-size: 13px;
}

.ql-list b { font-weight: 400; }
.ql-list span { flex: 1; color: var(--glass-muted); font-size: 12px; }
.ql-list em {
  color: var(--glass-muted);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 11.5px;
  font-style: normal;
}

.ql-foot {
  margin-top: 14px !important;
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 10.5px;
}

@media (prefers-reduced-motion: reduce) {
  .quicklook, .ql-panel { transition-duration: 1ms; }
}

/* ---------------------------------------------------------- Mission Control */
/* Two layers with the windows sandwiched between them: the dim sits under
   them, the click targets sit over them. */
.expose-dim {
  position: fixed;
  z-index: 8;
  inset: 0;
  background: rgba(0, 0, 0, 0.42);
  opacity: 0;
  transition: opacity 280ms ease;
}

.expose-dim[hidden] { display: none; }
.expose-dim.is-on { opacity: 1; }

.expose-hits {
  position: fixed;
  z-index: 25;
  inset: 0;
}

.expose-hits[hidden] { display: none; }

.expose-hit {
  position: absolute;
  border: 0;
  border-radius: 10px;
  background: transparent;
  cursor: pointer;
  /* The ring is drawn outside the box so it frames the thumbnail rather than
     covering its edge. */
  box-shadow: 0 0 0 0 rgba(216, 166, 87, 0);
  transition: box-shadow 160ms ease;
}

.expose-hit.is-picked { box-shadow: 0 0 0 3px var(--accent); }

.expose-name {
  position: absolute;
  top: calc(100% + 7px);
  left: 50%;
  padding: 2px 9px;
  border-radius: 6px;
  background: rgba(0, 0, 0, 0.55);
  color: var(--glass-text);
  font-family: var(--ui-font);
  font-size: 12px;
  white-space: nowrap;
  transform: translateX(-50%);
}

@media (min-width: 901px) {
  /* Scaled from the top-left so the transform maths is a plain offset, and
     inert so the pages inside cannot take a click meant for the thumbnail. */
  .app-window.is-exposed {
    z-index: 22;
    pointer-events: none;
    transform-origin: 0 0;
    transition: transform 320ms cubic-bezier(0.32, 0.72, 0, 1);
  }
}

@media (prefers-reduced-motion: reduce) {
  .app-window.is-exposed,
  .expose-dim { transition-duration: 1ms; }
}

/* ----------------------------------------------------- Notification Center */
.notif {
  position: fixed;
  z-index: 45;
  top: var(--menubar-h);
  right: 0;
  bottom: 0;
  width: 336px;
  max-width: 92vw;
  display: flex;
  flex-direction: column;
  gap: 12px;
  padding: 14px;
  overflow-y: auto;
  background: var(--glass);
  border-left: 1px solid var(--glass-hairline);
  font-family: var(--ui-font);
  backdrop-filter: saturate(180%) blur(30px);
  transform: translateX(100%);
  transition: transform 280ms cubic-bezier(0.32, 0.72, 0, 1);
  scrollbar-width: thin;
}

.notif[hidden] { display: none; }
.notif.is-open { transform: none; }

.widget {
  padding: 14px 15px;
  border: 1px solid rgba(255, 255, 255, 0.1);
  border-radius: 14px;
  background: var(--raised);
}

.widget-clock { text-align: center; }

.widget-date {
  margin: 0;
  color: var(--glass-muted);
  font-size: 12px;
}

.widget-time {
  margin: 2px 0 0;
  color: var(--glass-text);
  font-size: 38px;
  font-weight: 250;
  letter-spacing: -0.02em;
  line-height: 1.05;
}

.widget-feed header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 10px;
  color: var(--glass-text);
  font-size: 12px;
}

.widget-mark svg { width: 15px; height: 15px; display: block; }
.widget-feed header b { flex: 1; font-weight: 500; }

.widget-feed header button {
  border: 0;
  padding: 2px 4px;
  border-radius: 5px;
  background: transparent;
  color: var(--glass-muted);
  font-size: 13px;
  cursor: pointer;
}

.widget-feed header button:hover { background: var(--glass-hover); color: var(--glass-text); }

.widget-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

.feed-row {
  width: 100%;
  display: flex;
  align-items: flex-start;
  gap: 9px;
  padding: 7px 8px;
  border: 0;
  border-radius: 8px;
  background: transparent;
  color: var(--glass-text);
  font-family: inherit;
  font-size: 12px;
  text-align: left;
  cursor: pointer;
}

.feed-row:hover { background: var(--glass-hover); }

.feed-glyph {
  flex: none;
  width: 14px;
  color: var(--accent);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  line-height: 1.45;
}

.feed-body {
  flex: 1;
  min-width: 0;
  display: grid;
}

.feed-body b { font-weight: 400; }

.feed-body small {
  overflow: hidden;
  color: var(--glass-muted);
  font-size: 11px;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.feed-when {
  flex: none;
  color: var(--glass-dim);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 10.5px;
  line-height: 1.5;
}

.widget-feed footer {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--glass-hairline);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 10px;
  letter-spacing: 0.04em;
}

.widget-feed footer.is-dim { color: var(--dim); }
.widget-feed footer.is-err { color: var(--red); }

@media (prefers-reduced-motion: reduce) {
  .notif { transition-duration: 1ms; }
}

/* ------------------------------------------------------------------- Power */
/* The screen itself. Above every window and the dock, below nothing — when the
   machine is off, it is off. */
.power {
  position: fixed;
  z-index: 400;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: 26px;
  background: #000;
  opacity: 0;
  transition: opacity 620ms ease;
}

.power[hidden] { display: none; }
.power.is-lit { opacity: 1; }

/* The screensaver fills the sleeping screen; everything else in .power sits on
   top of it as a normal grid item. */
.power-saver {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 1100ms ease;
}

.power-saver[hidden] { display: none; }
.power-saver.is-on { opacity: 1; }

.power-boot {
  position: relative;
  display: grid;
  justify-items: center;
  gap: 38px;
  animation: power-fade 700ms ease both;
}

.power-boot[hidden] { display: none; }

@keyframes power-fade {
  from { opacity: 0; }
  to { opacity: 1; }
}

.power-apple {
  width: 68px;
  height: 68px;
  color: #f2f2f4;
}

.power-progress {
  width: 232px;
  height: 5px;
  border-radius: 3px;
  background: var(--glass-active);
  overflow: hidden;
}

.power-progress i {
  display: block;
  width: 0;
  height: 100%;
  border-radius: 3px;
  background: #f2f2f4;
  transition: width 520ms cubic-bezier(0.4, 0, 0.2, 1);
}

.power-button {
  width: 54px;
  height: 54px;
  display: grid;
  place-items: center;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 50%;
  background: var(--glass-hairline);
  color: var(--glass-muted);
  cursor: pointer;
  animation: power-fade 900ms ease both;
  transition: color 180ms ease, border-color 180ms ease, background 180ms ease;
}

.power-button[hidden] { display: none; }

.power-button:hover,
.power-button:focus-visible {
  border-color: rgba(255, 255, 255, 0.4);
  background: var(--glass-hover);
  color: #f2f2f4;
  outline: 0;
}

.power-button svg { width: 26px; height: 26px; }

.power-hint {
  position: relative;
  margin: 0;
  color: rgba(255, 255, 255, 0.3);
  font-size: 11px;
  letter-spacing: 0.09em;
  animation: power-fade 900ms ease both;
}

.power-hint[hidden] { display: none; }

.power-button { position: relative; }

/* The confirmation panel, sized and worded like the real one — narrow, centered,
   with the default button carrying the return key. */
.alert-layer {
  position: fixed;
  z-index: 320;
  inset: 0;
  display: grid;
  align-content: start;
  justify-items: center;
  padding-top: 18vh;
}

.alert-layer[hidden] { display: none; }

.mac-alert {
  width: 272px;
  display: grid;
  justify-items: center;
  gap: 9px;
  padding: 18px 16px 14px;
  border: 1px solid var(--glass-line);
  border-radius: 12px;
  background: var(--glass);
  box-shadow: 0 24px 64px var(--shadow-strong);
  font-family: var(--ui-font);
  text-align: center;
  backdrop-filter: saturate(180%) blur(24px);
  animation: alert-in 140ms ease-out;
}

@keyframes alert-in {
  from { opacity: 0; transform: scale(0.96); }
  to { opacity: 1; transform: none; }
}

.alert-mark {
  width: 42px;
  height: 42px;
  color: #e9ebef;
}

.mac-alert h2 {
  margin: 0;
  color: var(--glass-text);
  font-size: 13px;
  font-weight: 600;
  line-height: 1.35;
}

.mac-alert p {
  margin: 0;
  color: rgba(255, 255, 255, 0.62);
  font-size: 11px;
  line-height: 1.4;
}

.alert-check {
  display: flex;
  align-items: center;
  gap: 6px;
  margin-top: 2px;
  color: rgba(255, 255, 255, 0.72);
  font-size: 11px;
  cursor: default;
}

.alert-check input { margin: 0; accent-color: var(--sel); }

.alert-buttons {
  width: 100%;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 6px;
}

.alert-buttons button {
  padding: 5px 10px;
  border: 1px solid var(--glass-line);
  border-radius: 6px;
  background: rgba(255, 255, 255, 0.09);
  color: var(--glass-text);
  font-family: var(--ui-font);
  font-size: 12px;
  cursor: default;
}

.alert-buttons button:hover { background: rgba(255, 255, 255, 0.15); }

.alert-buttons .is-default {
  border-color: transparent;
  background: var(--sel);
  color: #fff;
}

.alert-buttons .is-default:hover { background: #3a78dc; }
.alert-buttons button:focus-visible { outline: 2px solid rgba(255, 255, 255, 0.5); outline-offset: 1px; }

/* --------------------------------------------------------------- Spotlight */
/* Chrome borrowed from macOS; typography borrowed from the terminal, so the
   panel belongs to this site rather than to a generic command palette.
   Deliberately no backdrop dimming — the desktop stays exactly as bright as
   it was. */
.spotlight {
  position: fixed;
  z-index: 150;
  inset: 0;
  display: grid;
  align-items: start;
  justify-items: center;
  padding: 14vh 20px 20px;
}

.spotlight[hidden] { display: none; }

.spotlight-panel {
  width: min(680px, 100%);
  border: 1px solid var(--glass-line);
  border-radius: 14px;
  background: var(--glass);
  box-shadow:
    0 28px 70px rgba(0, 0, 0, 0.55),
    0 2px 8px rgba(0, 0, 0, 0.45),
    inset 0 1px 0 rgba(255, 255, 255, 0.07);
  backdrop-filter: saturate(180%) blur(30px);
  overflow: hidden;
  animation: spotlight-in 130ms ease-out;
}

@keyframes spotlight-in {
  from { opacity: 0; transform: translateY(-6px) scale(0.99); }
  to { opacity: 1; transform: none; }
}

.spotlight-field {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 0 16px;
  height: 58px;
}

.spotlight-glass {
  flex: none;
  width: 22px;
  height: 22px;
  color: var(--glass-muted);
}

.spotlight-field input {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--glass-text);
  font-family: var(--ui-font);
  font-size: 24px;
  font-weight: 300;
  letter-spacing: -0.01em;
}

.spotlight-field input:focus { outline: 0; }
.spotlight-field input::placeholder { color: var(--glass-dim); }

.spotlight-flash {
  flex: none;
  padding: 2px 7px;
  border-radius: 4px;
  background: rgba(216, 166, 87, 0.16);
  color: var(--accent);
  font-size: 11px;
  letter-spacing: 0.04em;
}

.spotlight-flash[hidden] { display: none; }

.spotlight-body {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 232px;
  border-top: 1px solid rgba(255, 255, 255, 0.11);
  max-height: min(420px, 52vh);
}

.spotlight-body[hidden] { display: none; }

.spotlight-results {
  overflow-y: auto;
  padding: 6px 6px 8px;
  scrollbar-width: thin;
}

/* Group headings in the terminal's voice: lowercase, mono, on the quiet side. */
.spotlight-group {
  padding: 9px 10px 3px;
  color: var(--dim);
  font-size: 10px;
  letter-spacing: 0.1em;
  text-transform: lowercase;
}

.spotlight-row {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 10px;
  height: 28px;
  padding: 0 10px;
  border: 0;
  border-radius: 6px;
  background: transparent;
  color: var(--glass-text);
  font-family: var(--ui-font);
  font-size: 13px;
  text-align: left;
  cursor: default;
}

.spotlight-row.is-top { height: 44px; }

.spotlight-row.is-selected { background: var(--sel); color: var(--sel-ink); }

.spotlight-icon {
  flex: none;
  display: grid;
  place-items: center;
  object-fit: contain;
}

.spotlight-glyph {
  color: var(--accent);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  line-height: 1;
}

.spotlight-row.is-selected .spotlight-glyph { color: var(--sel-ink); }

.spotlight-label {
  flex: 1;
  min-width: 0;
  display: grid;
}

.spotlight-label b {
  overflow: hidden;
  font-weight: 400;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.spotlight-row.is-top .spotlight-label b { font-weight: 500; }

.spotlight-label small {
  overflow: hidden;
  color: var(--glass-muted);
  font-size: 11px;
  white-space: nowrap;
  text-overflow: ellipsis;
}

.spotlight-row.is-selected .spotlight-label small { color: rgba(255, 255, 255, 0.72); }

.spotlight-meta {
  flex: none;
  color: var(--glass-muted);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 11px;
}

.spotlight-row.is-selected .spotlight-meta { color: rgba(255, 255, 255, 0.75); }

.spotlight-empty {
  padding: 22px 12px;
  color: var(--dim);
  font-family: var(--ui-font);
  font-size: 13px;
  text-align: center;
}

/* Preview: what the selected thing actually is, before you commit to opening it. */
.spotlight-preview {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 16px 16px 12px;
  border-left: 1px solid var(--glass-hairline);
  overflow: hidden;
  font-family: var(--ui-font);
  text-align: center;
}

.spotlight-art {
  display: grid;
  place-items: center;
  height: 92px;
  margin-bottom: 2px;
}

.spotlight-art img {
  max-width: 100%;
  max-height: 92px;
  border-radius: 6px;
  object-fit: contain;
}

.spotlight-name {
  margin: 0;
  overflow: hidden;
  color: var(--glass-text);
  font-size: 14px;
  font-weight: 500;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.spotlight-kind {
  color: var(--muted);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 10.5px;
  letter-spacing: 0.06em;
  text-transform: lowercase;
}

.spotlight-answer {
  margin-top: 18px;
  color: var(--accent);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 26px;
  line-height: 1.15;
  overflow-wrap: anywhere;
}

.spotlight-facts {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  gap: 2px 10px;
  margin: 6px 0 0;
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 11px;
  text-align: left;
}

.spotlight-facts dt { color: var(--dim); }

.spotlight-facts dd {
  margin: 0;
  overflow: hidden;
  color: var(--text);
  text-overflow: ellipsis;
  white-space: nowrap;
}

.spotlight-summary {
  margin: 4px 0 0;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 4;
  overflow: hidden;
  color: var(--muted);
  font-size: 11.5px;
  line-height: 1.45;
  text-align: left;
}

.spotlight-actions {
  display: flex;
  flex-direction: column;
  gap: 2px;
  margin-top: auto;
  padding-top: 10px;
  border-top: 1px solid var(--glass-hairline);
  color: var(--dim);
  font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
  font-size: 10.5px;
  text-align: left;
}

@media (max-width: 640px) {
  .spotlight-body { grid-template-columns: minmax(0, 1fr); }
  .spotlight-preview { display: none; }
}

@media (prefers-reduced-motion: reduce) {
  .spotlight-panel { animation: none; }
}

/* Below the desktop breakpoint there is no dock to restore from, so the
   traffic lights stay decorative. */
/* ------------------------------------------------------------------- Phone */
/* Off entirely on a desktop; it is the whole interface below the breakpoint. */
.phone,
.phone-topbar { display: none; }

@media (max-width: 900px) {
  /* iOS zooms the whole page whenever a field smaller than 16px takes focus.
     Sizing every text field at 16px is the only reliable way to stop it —
     maximum-scale is advisory on Safari. */
  input[type="text"],
  input[type="email"],
  input:not([type]),
  .compose textarea,
  textarea { font-size: 16px; }

  /* The shell comes up with it: a 10px prompt on a phone was unreadable in any
     case, so the log and the prompt move together. */
  .shell-scroll { font-size: 15.5px; }
  .shell-line input { font-size: 16px; }
  #krome-address { font-size: 16px; }

  .phone {
    position: fixed;
    z-index: 6;
    inset: 0;
    display: flex;
    flex-direction: column;
    padding: max(12px, env(safe-area-inset-top)) 22px max(10px, env(safe-area-inset-bottom));
    font-family: var(--ui-font);
    background: var(--wallpaper);
  }

  /* On a real iPhone these two duplicate the device's own chrome, so they are
     dropped there and kept everywhere else — a narrow desktop window has no
     status bar or home indicator of its own, and looks bare without them. */
  .is-ios .phone-status,
  .is-ios .phone-home { display: none; }

  /* Without the fake status bar, the first element needs its own top margin —
     that is the widget when there is one, the grid when there is not. */
  .is-ios .phone-widget,
  .is-ios .phone-grid:first-of-type { margin-top: 14px; }

  .phone-status {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 2px 6px 0;
    color: var(--wall-ink);
    font-size: 14px;
    font-weight: 600;
  }

  .phone-glyphs { display: flex; align-items: center; gap: 5px; }
  .phone-glyphs svg { height: 12px; width: auto; display: block; }

  /* An iOS widget: a card of live content sitting above the apps. */
  .phone-widget {
    display: block;
    width: 100%;
    margin-top: 26px;
    padding: 13px 15px 11px;
    border: 1px solid var(--glass-line);
    border-radius: 18px;
    background: var(--phone-card);
    color: var(--wall-ink);
    font-family: inherit;
    text-align: left;
    cursor: pointer;
    backdrop-filter: saturate(180%) blur(22px);
    -webkit-tap-highlight-color: transparent;
    transition: transform 140ms ease;
  }

  .phone-widget:active { transform: scale(0.98); }
  .phone-widget[hidden] { display: none; }

  .phone-widget header {
    display: flex;
    align-items: center;
    gap: 7px;
    margin-bottom: 9px;
    font-size: 12px;
  }

  .phone-widget header b { flex: 1; font-weight: 500; }
  .phone-widget .widget-mark svg { width: 14px; height: 14px; display: block; }

  .phone-widget time {
    color: var(--glass-muted);
    font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
    font-size: 10px;
  }

  .phone-widget ol {
    margin: 0;
    padding: 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 7px;
    list-style: none;
  }

  .phone-widget li {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    /* A grid item's default min-width is auto, so a long branch name refuses to
       shrink and pushes the timestamp off the card. */
    min-width: 0;
    font-size: 12px;
    line-height: 1.35;
  }

  .phone-widget li i {
    flex: none;
    width: 12px;
    color: var(--accent);
    font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
    font-style: normal;
  }

  .phone-widget li span {
    flex: 1;
    min-width: 0;
    overflow: hidden;
    color: var(--wall-ink);
    text-overflow: ellipsis;
    white-space: nowrap;
  }

  .phone-widget li em {
    flex: none;
    color: var(--glass-dim);
    font-family: "SFMono-Regular", "SF Mono", Menlo, monospace;
    font-size: 10px;
    font-style: normal;
  }

  .phone-widget .is-err { color: var(--red); }

  .phone-grid {
    flex: 1;
    align-content: start;
    display: grid;
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 22px 14px;
    margin-top: 34px;
  }

  .phone-app {
    display: grid;
    justify-items: center;
    gap: 6px;
    border: 0;
    padding: 0;
    background: transparent;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }

  .phone-app:active .phone-tile { transform: scale(0.9); }

  .phone-tile {
    width: 60px;
    height: 60px;
    display: grid;
    place-items: center;
    /* iOS' squircle is a fat radius, not a circle. */
    border-radius: 15px;
    background: linear-gradient(180deg, #3a4350 0%, #1b2028 100%);
    color: #fff;
    font-size: 26px;
    overflow: hidden;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
    transition: transform 140ms ease;
  }

  .phone-tile img { width: 100%; height: 100%; object-fit: cover; display: block; }

  .phone-tile.is-mac {
    background: none;
    box-shadow: none;
    filter: drop-shadow(0 4px 10px rgba(0, 0, 0, 0.45));
  }

  /* Scaled, not sized: a percentage height here resolves against a grid row
     that the image itself sizes, so the browser applies it twice and the icon
     comes out stretched and hanging low. A transform has no such loop, and it
     scales about the center. */
  /* macOS artwork carries its own transparent margin, so it has to be scaled up
     to read at the same size as the flat tiles beside it. 1.24 puts the blue
     squircle at 59 of the tile's 60px — any more and `overflow: hidden` squares
     off its corners. No vertical nudge: the squircle is centered in its canvas,
     and only the soft shadow around it is not. */
  .phone-tile.is-mac img { transform: scale(1.24); }
  .phone-tile svg { width: 40px; height: 40px; }
  .phone-tile b { font-weight: 400; line-height: 1; }

  .phone-tile.is-violet { background: linear-gradient(180deg, #8b5cf6 0%, #4c1d95 100%); }
  .phone-tile.is-blue { background: linear-gradient(180deg, #38bdf8 0%, #0369a1 100%); }
  .phone-tile.is-teal { background: linear-gradient(180deg, #2dd4a7 0%, #0f766e 100%); }
  .phone-tile.is-slate { background: linear-gradient(180deg, #2b3440 0%, #0d1117 100%); color: var(--accent); }
  .phone-tile.is-white { background: linear-gradient(180deg, #ffffff 0%, #d5d9de 100%); color: #14181d; }

  .phone-app small {
    max-width: 100%;
    overflow: hidden;
    color: var(--wall-ink);
    font-size: 11px;
    text-align: center;
    text-overflow: ellipsis;
    text-shadow: var(--wall-ink-shadow);
    white-space: nowrap;
  }

  /* iOS hides search behind a pull-down, which nobody discovers on a website —
     so the gesture is wired up and a pill advertises it. */
  .phone-search {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: 7px;
    width: max-content;
    margin: 0 auto 16px;
    padding: 7px 16px;
    border: 0;
    border-radius: 999px;
    background: var(--phone-pill);
    color: var(--wall-ink);
    font-family: inherit;
    font-size: 13px;
    font-weight: 500;
    cursor: pointer;
    backdrop-filter: blur(16px);
    -webkit-tap-highlight-color: transparent;
  }

  .phone-search:active { background: var(--glass-active); }
  .phone-search svg { width: 15px; height: 15px; }

  /* Spotlight sits nearer the top on a phone: the keyboard takes the bottom
     half the moment it opens. */
  .spotlight { padding-top: 7vh; }
  .spotlight-field { height: 52px; }
  .spotlight-field input { font-size: 19px; }
  .spotlight-body { max-height: 46vh; }

  .phone-dock {
    display: flex;
    justify-content: center;
    gap: 26px;
    padding: 14px 18px;
    border: 1px solid rgba(255, 255, 255, 0.14);
    border-radius: 26px;
    background: rgba(190, 200, 214, 0.16);
    backdrop-filter: saturate(180%) blur(24px);
  }

  .phone-dock .phone-app small { display: none; }

  .phone-home {
    width: 128px;
    height: 5px;
    margin: 9px auto 2px;
    border-radius: 3px;
    background: var(--phone-bar);
  }

  /* An open app covers the home screen; the terminal window is the surface it
     is drawn on, so the desktop's own markup is reused rather than duplicated. */
  #terminal-window {
    position: fixed;
    z-index: 7;
    inset: 0;
    transform: translateY(100%);
    transition: transform 300ms cubic-bezier(0.32, 0.72, 0, 1);
  }

  body.phone-app-open #terminal-window { transform: none; }

  .phone-topbar {
    position: fixed;
    z-index: 8;
    top: 0;
    left: 0;
    right: 0;
    height: calc(46px + env(safe-area-inset-top));
    display: none;
    align-items: center;
    gap: 6px;
    padding: env(safe-area-inset-top) 12px 0;
    background: rgba(16, 20, 26, 0.92);
    border-bottom: 1px solid var(--line);
    font-family: var(--ui-font);
    backdrop-filter: blur(18px);
  }

  /* Both classes, or the browser opens with no way back to the home screen. */
  body.phone-app-open .phone-topbar,
  body.phone-krome-open .phone-topbar { display: flex; }

  .phone-topbar button {
    width: 34px;
    height: 34px;
    display: grid;
    place-items: center;
    border: 0;
    border-radius: 8px;
    background: transparent;
    color: var(--accent);
    cursor: pointer;
  }

  .phone-topbar button svg { width: 20px; height: 20px; }
  .phone-topbar strong { color: var(--text); font-size: 15px; font-weight: 500; }

  /* The phone title bar replaces the window's own chrome — running both put the
     tab strip underneath it, half-clipped. Sections are switched from the home
     screen here, the way they are on a phone. */
  body.phone-app-open .topbar { display: none; }
  body.phone-app-open #terminal-window {
    grid-template-rows: minmax(0, 1fr) auto;
    /* Opaque, or the home screen underneath shows through the gap between the
       workspace and the status bar. */
    background: var(--bg);
  }
  body.phone-app-open .workspace { padding-top: calc(46px + env(safe-area-inset-top)); }

  .window-controls button { pointer-events: none; cursor: default; }

  .window-controls:hover button::before,
  .window-controls:hover button::after { opacity: 0; }

  /* Krome is the exception: it covers the whole screen here, so its lights
     have to stay live — they are the only way back out. */
  .krome-window .window-controls { display: flex; }
  .krome-window .window-controls button { pointer-events: auto; cursor: pointer; }

  .krome-window .window-controls:hover button::before,
  .krome-window .window-controls:hover button::after { opacity: 1; }

  /* ------------------------------------------------------- Krome on a phone */
  /* A phone browser is one page at a time: no tab strip, no bookmarks bar, and
     only the controls that fit — back, forward, reload and the address. */
  body.phone-krome-open .krome-window {
    position: fixed;
    z-index: 7;
    inset: calc(46px + env(safe-area-inset-top)) 0 0;
    max-width: none;
    max-height: none;
    border-radius: 0;
    grid-template-rows: 44px minmax(0, 1fr);
  }

  body.phone-krome-open .krome-tabstrip,
  body.phone-krome-open .krome-bookmarks,
  body.phone-krome-open .krome-star,
  body.phone-krome-open .krome-puzzle,
  body.phone-krome-open .krome-dots,
  body.phone-krome-open .krome-avatar { display: none; }

  body.phone-krome-open .krome-toolbar {
    gap: 2px;
    padding: 0 8px;
  }

  body.phone-krome-open .krome-omnibox { height: 34px; }
  body.phone-krome-open .krome-omnibox input { font-size: 16px; } /* iOS zooms below 16 */
}

@media (max-width: 760px) {
  :root { font-size: 12px; }
  .topbar { padding-inline: 0.55rem; }
  .window-controls, .brand span { display: none; }
  .tabs { gap: 0.2rem; }
  .tabs i { display: none; }

  /* Stacked, not side by side. Two 44% columns on a 390px screen left the
     device names truncated to "authapi.dev…" with the detail beside them
     squeezed into a gutter. */
  .workspace-panel {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: auto minmax(0, 1fr);
    gap: 18px;
  }

  .list-pane { max-height: 42vh; }
  .workspace-panel.is-shell { grid-template-rows: minmax(0, 1fr); }
  .is-shell .shell-pane { max-height: none; }
  .list-head { display: none; }

  /* Hardware's five-column rule is an ID selector, so it has to be answered with
     one here — otherwise the desktop measure survives on a phone and squeezes
     the device name down to nothing. */
  .list-row,
  #panel-hardware .list-row {
    grid-template-columns: 0.8rem minmax(0, 1fr);
    gap: 0.45rem;
  }

  .list-row > span:nth-child(n+3) { display: none; }
  .filter { font-size: 0.7rem; }
  .detail-title { min-height: 70px; }
  /* Only the mode block, the position and the help hint fit on a phone. */
  .keys,
  .where { display: none; }
  .statusbar { grid-template-columns: auto 1fr auto; }
}

@media (max-width: 480px) {
  .list-pane { padding-inline: 0.25rem; }
  .filter { padding-inline: 0.3rem; }
  .list-row { padding-inline: 0.35rem; }
  .detail-tabs span { display: none; }
  .property { grid-template-columns: 1fr; gap: 0; }
  .property span::after { content: none; }
}

@media (prefers-reduced-motion: reduce) {
  .app-window,
  .krome-tab,
  .dock-app { transition-duration: 1ms; }
}
