:root {
  --cream: #faf3e3;
  --ink: #1c1c1c;
  --muted: #6b5f5e;
  --line: rgba(28, 28, 28, 0.12);
  --panel: #fffdf8;
  --font: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --display: "Fraunces", Georgia, serif;
  --mono: "DM Mono", ui-monospace, monospace;
  --nav-h: calc(3.25rem + env(safe-area-inset-top, 0px));
  --sn-radius: 10px;
  --gutter: clamp(18px, 2.4vw, 40px);
  /* Where a filed card flies to. Overridden when the memory sidebar is open. */
  --file-x: 40px;
  --file-y: -40px;
}

*, *::before, *::after { box-sizing: border-box; }

/* Chrome here is toggled with the `hidden` attribute, and most of it is a flex
   or grid box — which would otherwise beat the user-agent `display: none`. */
[hidden] { display: none !important; }

html, body {
  margin: 0;
  height: 100%;
  background: var(--cream);
  color: var(--ink);
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.5;
}

/* Phone editing: iOS must not scroll or scale the document. */
html.sn-editing,
html.sn-editing body {
  overflow: hidden;
  overscroll-behavior: none;
}

/* Keyboard is a layout inset: the shell fills the visual viewport, so the
   dotted canvas is the remaining space above the keys. Height/top are
   interpolated in JS (`--sn-vv-*`) so the whiteboard slides rather than
   jumps. No camera pan. The site nav stays up and keeps its safe-area
   padding — hiding it is what put BOARD/MEMORY under the clock. */
html.sn-kb-inset,
html.sn-kb-inset body {
  height: var(--sn-vv-height);
  min-height: 0;
  overflow: hidden;
  overscroll-behavior: none;
}
html.sn-kb-inset body {
  position: fixed;
  top: var(--sn-vv-top, 0px);
  left: 0;
  right: 0;
  width: 100%;
}

/* The board is the page: column shell, no page scroll, canvas takes the rest. */
body {
  display: flex;
  flex-direction: column;
  min-height: 100dvh;
}

a { color: var(--ink); }

/* ---------------------------------------------------------------- nav */

.sn-nav {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  min-height: var(--nav-h);
  height: var(--nav-h);
  padding: 0 clamp(12px, 2vw, 24px);
  padding-top: env(safe-area-inset-top, 0px);
  border-bottom: 1.5px solid var(--line);
  background: rgba(250, 243, 227, 0.92);
  backdrop-filter: blur(8px);
  z-index: 30;
}

.sn-nav-brand { display: flex; align-items: center; gap: 10px; min-width: 0; }

.sn-nav-logo,
.sn-nav-section {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  color: var(--ink);
}

.sn-nav-logo {
  font-family: var(--mono);
  font-size: 0.72rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.65;
}
.sn-nav-logo:hover { opacity: 1; }

.sn-nav-section { font-family: var(--display); font-size: 1.15rem; white-space: nowrap; }

.sn-nav-links {
  display: flex;
  gap: 4px;
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  flex-wrap: wrap;
  justify-content: flex-end;
}
.sn-nav-links a {
  text-decoration: none;
  opacity: 0.55;
  min-height: 44px;
  padding: 0 10px;
  display: inline-flex;
  align-items: center;
}
.sn-nav-links a:hover { opacity: 1; }

/* The one thing that stays on screen after the guest strip is dismissed, so a
   local-only board is never quietly local. */
.sn-navchip {
  align-self: center;
  border: 1.5px solid var(--ink);
  background: transparent;
  color: var(--ink);
  border-radius: var(--sn-radius);
  font: inherit;
  letter-spacing: inherit;
  text-transform: uppercase;
  padding: 5px 10px;
  min-height: 32px;
  cursor: pointer;
  white-space: nowrap;
}
.sn-navchip:hover { background: var(--ink); color: var(--cream); }
.sn-nav-install,
.sn-nav-status {
  align-self: center;
  min-height: 32px;
  padding: 6px 10px;
  border: 1.5px solid var(--ink);
  border-radius: var(--sn-radius);
  background: transparent;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 0.62rem;
  line-height: 1;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  white-space: nowrap;
}
.sn-nav-install { cursor: pointer; }
.sn-nav-install:hover { background: var(--ink); color: var(--cream); }
.sn-nav-status {
  border-style: dashed;
  opacity: 0.72;
}

/* ---------------------------------------------------------------- shell */

.sn-shell {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
}

/* ---------------------------------------------------------------- guest strip */

/* Signed out the board works exactly the same; only saving is missing. This
   says so above the canvas rather than in a modal in front of it. */
.sn-guestbar {
  flex: none;
  display: flex;
  align-items: center;
  gap: 10px;
  margin: 8px 10px 0;
  padding: 8px 8px 8px 14px;
  border: 1.5px solid var(--ink);
  border-radius: var(--sn-radius);
  background: var(--panel);
  font-family: var(--mono);
  font-size: 0.68rem;
  letter-spacing: 0.03em;
}

.sn-guestbar-text { min-width: 0; }

.sn-guestbar-cta {
  flex: none;
  margin-left: auto;
  background: var(--ink);
  color: var(--cream);
  border: 1.5px solid var(--ink);
  border-radius: var(--sn-radius);
  padding: 7px 12px;
  min-height: 32px;
  display: inline-flex;
  align-items: center;
  text-decoration: none;
  text-transform: uppercase;
  white-space: nowrap;
  font: inherit;
  font-size: 0.72rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  cursor: pointer;
}

.sn-guestbar-close {
  flex: none;
  border: 1.5px solid var(--line);
  background: transparent;
  color: var(--ink);
  border-radius: var(--sn-radius);
  width: 32px;
  height: 32px;
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}
.sn-guestbar-close:hover { background: var(--ink); color: var(--cream); }

.sn-app {
  flex: 1;
  min-height: 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 8px 10px 10px;
  overflow: hidden;
}

/* ---------------------------------------------------------------- toolbar */

/* Desktop: one left-aligned row. Phone (max-width 719px) wraps to two rows. */
.sn-toolbar {
  flex: none;
  display: flex;
  flex-wrap: nowrap;
  gap: 8px;
  align-items: center;
  justify-content: flex-start;
  min-height: 44px;
}

.sn-tabs { display: inline-flex; gap: 4px; flex: none; }

.sn-tab {
  font-family: var(--mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border: 1.5px solid var(--line);
  background: transparent;
  color: var(--ink);
  border-radius: var(--sn-radius);
  padding: 8px 14px;
  cursor: pointer;
  min-height: 40px;
  opacity: 0.6;
  white-space: nowrap;
}
.sn-tab[aria-selected="true"] { border-color: var(--ink); background: var(--panel); opacity: 1; }

.sn-tab-count {
  font-size: 0.62rem;
  background: var(--ink);
  color: var(--cream);
  border-radius: var(--sn-radius);
  padding: 1px 7px;
  margin-left: 4px;
}
.sn-tab-count:empty { display: none; }

/* A note landing in memory should be noticed even when memory is off screen. */
.sn-tab-count.is-bumped,
.sn-side-count.is-bumped { animation: sn-bump 420ms ease; }
@keyframes sn-bump {
  0% { transform: scale(1); }
  40% { transform: scale(1.45); }
  100% { transform: scale(1); }
}

.sn-toolbar-actions {
  display: flex;
  gap: 8px;
  align-items: center;
  min-width: 0;
}

.sn-board-actions { display: flex; gap: 8px; align-items: center; min-width: 0; }

.sn-view-toggle {
  display: inline-flex;
  flex: none;
  border: 1.5px solid var(--line);
  border-radius: var(--sn-radius);
  overflow: hidden;
  background: var(--panel);
}
.sn-view-toggle button {
  width: 36px;
  height: 36px;
  border: 0;
  background: transparent;
  color: var(--ink);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 8px;
  opacity: 0.45;
}
.sn-view-toggle button svg { width: 100%; height: 100%; }
.sn-view-toggle button[aria-pressed="true"] {
  background: var(--ink);
  color: var(--cream);
  opacity: 1;
}

html.sn-table-view .sn-btn-pen,
html.sn-table-view #zoom-controls,
html.sn-table-view #select-all,
html.sn-table-view #menu-select-all,
html.sn-table-view #menu-fit { display: none !important; }

.sn-btn {
  font-family: var(--mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  border: 1.5px solid var(--ink);
  background: var(--panel);
  color: var(--ink);
  border-radius: var(--sn-radius);
  padding: 8px 14px;
  cursor: pointer;
  min-height: 40px;
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  white-space: nowrap;
}
.sn-btn:hover { filter: brightness(0.98); }
.sn-btn-primary { background: var(--ink); color: var(--cream); }

/* The create control is a + and nothing else — a note starts blank, and so
   does its button. The name lives in aria-label / title. */
.sn-btn.sn-btn-add {
  width: 40px;
  padding: 0;
  justify-content: center;
  font-size: 1.1rem;
  line-height: 1;
  flex: none;
}

.sn-iconbtn {
  border: 1.5px solid var(--line);
  background: var(--panel);
  color: var(--ink);
  border-radius: var(--sn-radius);
  width: 40px;
  height: 40px;
  flex: none;
  font-family: var(--mono);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.sn-iconbtn:hover,
.sn-iconbtn[aria-expanded="true"] { border-color: var(--ink); background: var(--ink); color: var(--cream); }

.sn-zoom {
  display: inline-flex;
  align-items: center;
  border: 1.5px solid var(--line);
  border-radius: var(--sn-radius);
  background: var(--panel);
  overflow: hidden;
  flex: none;
}
.sn-zoom-btn,
.sn-zoom-label {
  border: 0;
  background: transparent;
  font-family: var(--mono);
  font-size: 0.7rem;
  min-height: 40px;
  padding: 0 12px;
  cursor: pointer;
  color: var(--ink);
}
.sn-zoom-label { border-left: 1.5px solid var(--line); border-right: 1.5px solid var(--line); min-width: 60px; }
.sn-zoom-center {
  border-left: 1.5px solid var(--line);
  padding: 0 10px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.sn-zoom-center svg { width: 15px; height: 15px; display: block; }
.sn-zoom-btn:hover, .sn-zoom-label:hover { background: rgba(28, 28, 28, 0.04); }

.sn-more { position: relative; display: inline-flex; }

.sn-menu {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 45;
  display: flex;
  flex-direction: column;
  min-width: 190px;
  background: var(--panel);
  border: 1.5px solid var(--ink);
  border-radius: 12px;
  padding: 4px;
  box-shadow: 0 10px 28px rgba(28, 28, 28, 0.22);
}

.sn-menu-item {
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 0.7rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  text-align: left;
  padding: 11px 12px;
  min-height: 44px;
  border-radius: 8px;
  cursor: pointer;
}
.sn-menu-item:hover { background: rgba(28, 28, 28, 0.06); }

/* ---------------------------------------------------------------- workspace */

.sn-workspace {
  flex: 1;
  min-height: 0;
  display: flex;
  gap: 10px;
}

.sn-viewport {
  position: relative;
  flex: 1;
  min-width: 0;
  min-height: 0;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  overflow: hidden;
  background-color: var(--panel);
  background-image: radial-gradient(rgba(28, 28, 28, 0.07) 1px, transparent 1px);
  background-size: 22px 22px;
  touch-action: none;
  outline: none;
  cursor: default;
}
.sn-viewport.is-pan-ready { cursor: grab; }
.sn-viewport.is-panning { cursor: grabbing; }
/* Long-press selection mode: taps add notes instead of opening the editor. */
.sn-viewport.is-selecting { background-color: #fbf7ec; }

.sn-world {
  position: absolute;
  left: 0;
  top: 0;
  width: 0;
  height: 0;
  transform-origin: 0 0;
}

.sn-arrows {
  position: absolute;
  left: 0;
  top: 0;
  width: 1px;
  height: 1px;
  overflow: visible;
  color: rgba(28, 28, 28, 0.55);
}

.sn-arrow-line { stroke: currentColor; stroke-width: 1.5; }
.sn-arrow-hit { stroke: transparent; stroke-width: 14; }
.sn-arrow-del { opacity: 0; cursor: pointer; }
.sn-arrow-del circle { fill: var(--panel); stroke: var(--ink); stroke-width: 1.2; }
.sn-arrow-del path { stroke: var(--ink); stroke-width: 1.4; }
.sn-arrow:hover .sn-arrow-line { stroke-width: 2.5; }
.sn-arrow:hover .sn-arrow-del { opacity: 1; }
.sn-arrow-ghost {
  stroke: rgba(28, 28, 28, 0.4);
  stroke-width: 1.5;
  stroke-dasharray: 5 4;
}

.sn-rubber {
  position: absolute;
  border: 1.5px dashed var(--ink);
  background: rgba(28, 28, 28, 0.06);
  pointer-events: none;
  z-index: 15;
}

.sn-empty {
  position: absolute;
  inset: 0;
  display: grid;
  place-content: center;
  place-items: center;
  gap: 6px;
  text-align: center;
  padding: 24px;
  pointer-events: none;
  color: rgba(28, 28, 28, 0.5);
  font-family: var(--mono);
  font-size: 0.82rem;
  letter-spacing: 0.04em;
}
.sn-empty p { margin: 0; }
.sn-empty-line { font-size: 0.95rem; color: rgba(28, 28, 28, 0.65); }
.sn-empty-sub { max-width: 34ch; line-height: 1.7; }
.sn-empty kbd {
  border: 1px solid var(--line);
  border-radius: 4px;
  padding: 1px 5px;
  background: var(--cream);
}

/* ---------------------------------------------------------------- first-use hint */

.sn-hintstrip {
  position: absolute;
  top: 10px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 18;
  display: flex;
  align-items: center;
  gap: 10px;
  max-width: calc(100% - 20px);
  background: var(--cream);
  border: 1.5px solid var(--ink);
  border-radius: var(--sn-radius);
  padding: 5px 6px 5px 14px;
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.03em;
  box-shadow: 0 4px 14px rgba(28, 28, 28, 0.1);
}
.sn-hintstrip span { min-width: 0; }

.sn-hint-dismiss {
  flex: none;
  border: 1.5px solid var(--line);
  background: var(--panel);
  color: var(--ink);
  border-radius: var(--sn-radius);
  font: inherit;
  text-transform: uppercase;
  padding: 6px 12px;
  min-height: 32px;
  cursor: pointer;
}
.sn-hint-dismiss:hover { background: var(--ink); color: var(--cream); }

/* ---------------------------------------------------------------- cards */

/* The colour a note carries fills the whole card — a sticky note is the
   colour, it does not wear a stripe. Uncoloured (pre-existing) notes keep the
   paper background. */
.sn-card {
  position: absolute;
  z-index: 2;
  background: var(--note-fill, var(--panel));
  border: 1.5px solid var(--line);
  border-radius: 10px;
  box-shadow: 0 1px 4px rgba(28, 28, 28, 0.08);
  min-height: 64px;
  padding: 10px 12px 8px;
  cursor: grab;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
  contain: layout style;
}
.sn-card.is-dragging { cursor: grabbing; box-shadow: 0 6px 18px rgba(28, 28, 28, 0.16); }
/* Two fingers are resizing this note: say so, since the card is under a hand
   and the only other feedback is its own edge moving. */
.sn-card.is-pinching {
  box-shadow: 0 10px 26px rgba(28, 28, 28, 0.22);
  outline: 2px solid var(--ink);
  outline-offset: 1px;
  z-index: 7;
}
.sn-card.is-editing {
  cursor: text;
  user-select: text;
  -webkit-user-select: text;
  box-shadow: 0 8px 22px rgba(28, 28, 28, 0.18);
  z-index: 6;
}
.sn-card.is-selected { outline: 2px solid var(--ink); outline-offset: 2px; }
/* A clipped picture with nothing written on it is shown as the picture: no
   padding, no border, no paper behind it — just the image, wearing the card's
   own corner radius. Board.js only sets this when the note is purely a still
   (isPhotoNote), and takes it off again while the note is being edited. */
/* Not `overflow: hidden` — the pin hangs over the top edge. The media host
   clips the image itself, and inherits the radius to do it. */
.sn-card.is-photo {
  padding: 0;
  border: 0;
  background: transparent;
  min-height: 0;
}
.sn-card.is-photo .sn-card-body,
.sn-card.is-photo .sn-card-source { display: none; }
.sn-card.is-photo .sn-card-media {
  margin: 0;
  border: 0;
  border-radius: inherit;
}
/* An icon tag has to read against a photograph, not a cream card. */
.sn-card.is-photo .sn-card-icon {
  padding: 3px;
  width: 22px;
  height: 22px;
  background: rgba(250, 243, 227, 0.9);
  border-radius: 50%;
  opacity: 1;
}
.sn-card.is-pinned { box-shadow: 0 3px 10px rgba(28, 28, 28, 0.18); }
.sn-card.is-filing {
  transition: transform 200ms ease, opacity 200ms ease;
  transform: translate(var(--file-x), var(--file-y)) scale(0.6);
  opacity: 0;
  pointer-events: none;
}
/* Restored from memory — say where it landed. */
.sn-card.is-pulsing { animation: sn-pulse 900ms ease; }
@keyframes sn-pulse {
  0%, 100% { box-shadow: 0 1px 4px rgba(28, 28, 28, 0.08); }
  25%, 75% { box-shadow: 0 0 0 6px rgba(28, 28, 28, 0.14); }
}

.sn-card-pin {
  display: none;
  position: absolute;
  left: 10px;
  top: -9px;
  width: 18px;
  height: 18px;
  color: var(--ink);
  background: var(--cream);
  border: 1.5px solid var(--ink);
  border-radius: 50%;
  padding: 1px;
}
.sn-card.is-pinned .sn-card-pin { display: inline-flex; }
.sn-card-pin svg { width: 100%; height: 100%; }

.sn-card-icon {
  position: absolute;
  right: 7px;
  top: 7px;
  width: 18px;
  height: 18px;
  opacity: 0.75;
  pointer-events: none;
}
.sn-card-icon svg { width: 100%; height: 100%; }
.sn-card-icon:empty { display: none; }
.sn-custom-icon-image {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 4px;
  object-fit: cover;
}

.sn-card-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 3px;
  margin: 0 0 5px;
  max-height: 2.6em;
  overflow: hidden;
}

.sn-tag-pill {
  display: inline-block;
  max-width: 9ch;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--cream);
  border: 1px solid var(--line);
  color: var(--ink);
  font-size: 0.64rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: middle;
}

.sn-card-body {
  font-size: 0.92rem;
  line-height: 1.4;
  word-break: break-word;
  outline: none;
  padding-right: 16px;
  /* Click the body and you type — say so before the click. */
  cursor: text;
}

/* Formatting is bold plus two kinds of list, and nothing else. */
.sn-card-body b { font-weight: 700; }
.sn-card-body > div { white-space: pre-wrap; min-height: 1.4em; }
.sn-card-body ul,
.sn-card-body ol {
  margin: 0;
  padding-left: 1.2em;
}
.sn-card-body li { white-space: pre-wrap; }
.sn-card-body ul { list-style: disc; }
.sn-card-body ol { list-style: decimal; }
.sn-card-body li::marker { color: rgba(28, 28, 28, 0.55); }

.sn-card-media {
  position: relative;
  margin-top: 8px;
  width: 100%;
  overflow: hidden;
  border: 1.5px solid rgba(28, 28, 28, 0.42);
  border-radius: 8px;
  background:
    linear-gradient(135deg, rgba(250, 243, 227, 0.58), rgba(250, 243, 227, 0.25));
}
.sn-card-media.is-before {
  margin-top: 0;
  margin-bottom: 8px;
}
.sn-media-link,
.sn-media-play,
.sn-media-frame {
  display: block;
  width: 100%;
  height: 100%;
}
.sn-media-link { color: inherit; text-decoration: none; }
.sn-media-link iframe { pointer-events: none; }
.sn-media-play {
  position: relative;
  padding: 0;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
.sn-media-frame img,
.sn-media-frame iframe,
.sn-media-player {
  display: block;
  width: 100%;
  height: 100%;
}
.sn-media-frame img { object-fit: contain; }
.sn-card-media[data-fit="cover"] .sn-media-frame img { object-fit: cover; }
video.sn-media-player { object-fit: contain; }
.sn-media-frame iframe,
.sn-media-player {
  border: 0;
  background: var(--cream);
}
.sn-media-placeholder {
  display: grid;
  place-items: center;
  width: 100%;
  min-height: 72px;
  padding: 12px;
  font-family: var(--mono);
  font-size: 0.68rem;
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background:
    repeating-linear-gradient(-45deg, transparent 0 10px, rgba(28, 28, 28, 0.035) 10px 20px);
}
.sn-media-play-glyph {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 38px;
  height: 38px;
  transform: translate(-50%, -50%);
  border: 1.5px solid var(--line);
  border-radius: 50%;
  background: var(--cream);
  box-shadow: 0 2px 8px rgba(28, 28, 28, 0.18);
}
.sn-media-play-glyph::after {
  content: "";
  position: absolute;
  left: 14px;
  top: 10px;
  border-left: 12px solid var(--ink);
  border-top: 8px solid transparent;
  border-bottom: 8px solid transparent;
}
.sn-media-caption {
  position: absolute;
  left: 6px;
  bottom: 6px;
  z-index: 2;
  max-width: calc(100% - 12px);
  overflow: hidden;
  padding: 3px 7px;
  border: 1px solid rgba(28, 28, 28, 0.35);
  border-radius: 999px;
  background: rgba(250, 243, 227, 0.93);
  font-family: var(--mono);
  font-size: 0.58rem;
  line-height: 1.2;
  text-overflow: ellipsis;
  white-space: nowrap;
  pointer-events: none;
}

/* Deliberate way out to the source, for pointers that cannot click the
   preview itself. Hidden until a coarse pointer asks for it. */
.sn-media-open {
  display: none;
  position: absolute;
  /* Top-left: the caption owns the bottom-left, the resize handle the
     bottom-right, and an icon tag the top-right of the card. */
  left: 6px;
  top: 6px;
  z-index: 2;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: 1px solid rgba(28, 28, 28, 0.35);
  border-radius: 50%;
  background: rgba(250, 243, 227, 0.93);
  color: var(--ink);
  font-size: 0.82rem;
  line-height: 1;
  text-decoration: none;
}
.sn-media-open::after {
  content: "";
  position: absolute;
  inset: -7px; /* 30 + 14 = 44px hit */
}

.sn-card-source {
  font-family: var(--mono);
  font-size: 0.62rem;
  margin-top: 6px;
  opacity: 0.55;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.sn-card-source a { color: inherit; }

.sn-dot {
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--panel);
  border: 1.5px solid var(--ink);
  opacity: 0;
  cursor: crosshair;
  z-index: 5;
}
.sn-card:hover .sn-dot { opacity: 0.85; }
.sn-dot[data-side="n"] { top: -5px; left: calc(50% - 5px); }
.sn-dot[data-side="s"] { bottom: -5px; left: calc(50% - 5px); }
.sn-dot[data-side="e"] { right: -5px; top: calc(50% - 5px); }
.sn-dot[data-side="w"] { left: -5px; top: calc(50% - 5px); }

.sn-card-resize {
  position: absolute;
  right: 0;
  bottom: 0;
  width: 14px;
  height: 14px;
  cursor: nwse-resize;
  opacity: 0;
  background:
    linear-gradient(135deg, transparent 55%, rgba(28, 28, 28, 0.45) 55%, rgba(28, 28, 28, 0.45) 65%, transparent 65%,
      transparent 75%, rgba(28, 28, 28, 0.45) 75%, rgba(28, 28, 28, 0.45) 85%, transparent 85%);
  border-radius: 0 0 10px 0;
}
.sn-card:hover .sn-card-resize { opacity: 1; }

/* ---------------------------------------------------------------- board ink */

/* Text written on the board rather than on a note: no card, no fill, no pin.
   It is wiped with the board and never filed. */
.sn-ink {
  position: absolute;
  z-index: 1;
  /* The world layer is a 0×0 transform origin, so an absolutely positioned
     child has no width to lay text out in — it has to size to its content
     before max-width can cap it, or every word breaks to its own line. */
  width: max-content;
  max-width: 340px;
  padding: 2px 5px;
  margin: -2px -5px;
  font-family: var(--display);
  font-size: 1.15rem;
  line-height: 1.25;
  color: rgba(28, 28, 28, 0.78);
  white-space: pre-wrap;
  word-break: break-word;
  border: 1.5px dashed transparent;
  border-radius: 8px;
  outline: none;
  cursor: text;
  user-select: none;
  -webkit-user-select: none;
  -webkit-touch-callout: none;
}
.sn-ink:hover { border-color: rgba(28, 28, 28, 0.22); }
.sn-ink.is-dragging { border-color: rgba(28, 28, 28, 0.35); cursor: grabbing; }
.sn-ink.is-editing {
  border-color: var(--ink);
  background: rgba(255, 253, 248, 0.92);
  color: var(--ink);
  user-select: text;
  -webkit-user-select: text;
  z-index: 7;
}

/* The pen is armed: the next press writes on the board. */
.sn-viewport.is-writing { cursor: text; }
.sn-btn-pen[aria-pressed="true"] { background: var(--ink); color: var(--cream); }
.sn-pen-glyph { display: inline-flex; width: 15px; height: 15px; }
.sn-pen-glyph svg { width: 100%; height: 100%; }

/* ---------------------------------------------------------------- collection chips */

.sn-chip {
  position: absolute;
  display: inline-flex;
  align-items: center;
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  background: var(--cream);
  color: var(--ink);
  border: 1.5px solid var(--ink);
  border-radius: var(--sn-radius);
  padding: 0;
  white-space: nowrap;
  z-index: 4;
}
.sn-chip:hover { background: var(--ink); color: var(--cream); }
.sn-chip svg { width: 11px; height: 11px; }
.sn-chip-name,
.sn-chip-wiki {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  border: 0;
  background: transparent;
  color: inherit;
  font: inherit;
  text-transform: inherit;
  letter-spacing: inherit;
  cursor: pointer;
  padding: 3px 8px 3px 10px;
}
.sn-chip-wiki {
  padding: 3px 10px 3px 4px;
  min-width: 18px;
  min-height: 18px;
  border-left: 1px solid currentColor;
}
.sn-chip-wiki svg { width: 12px; height: 12px; }

/* ------------------------------------------------- phone compose (outside #world) */

/* Untransformed typing surface. iOS will open the keyboard into this;
   a contentEditable card inside a CSS-transformed #world will not. */
.sn-compose {
  position: fixed;
  z-index: 45;
  display: flex;
  flex-direction: column;
  box-sizing: border-box;
  min-height: 96px;
  max-height: 40vh;
  padding: 10px 12px;
  background: var(--note-fill, var(--panel));
  border: 1.5px solid var(--ink);
  border-radius: var(--sn-radius);
  box-shadow: 0 8px 22px rgba(28, 28, 28, 0.2);
  transform: none;
  touch-action: manipulation;
}
.sn-compose-body {
  flex: 1 1 auto;
  min-height: 4.2em;
  overflow-y: auto;
  font-size: 16px;
  line-height: 1.4;
  word-break: break-word;
  outline: none;
  cursor: text;
  -webkit-user-select: text;
  user-select: text;
}
.sn-compose-body b { font-weight: 700; }
.sn-compose-body > div { white-space: pre-wrap; min-height: 1.4em; }
.sn-compose-body ul,
.sn-compose-body ol {
  margin: 0;
  padding-left: 1.2em;
}
.sn-compose-body li { white-space: pre-wrap; }
.sn-compose-body ul { list-style: disc; }
.sn-compose-body ol { list-style: decimal; }
.sn-compose-body li::marker { color: rgba(28, 28, 28, 0.55); }

/* ------------------------------------------------- tier 1: the editing note's bar */

.sn-editbar {
  position: fixed;
  z-index: 46;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 2px;
  max-width: calc(100vw - 16px);
  background: var(--ink);
  color: var(--cream);
  border-radius: var(--sn-radius);
  padding: 3px;
  box-shadow: 0 6px 18px rgba(28, 28, 28, 0.28);
  /* A press on the bar must never be read as a double-tap-to-zoom. */
  touch-action: manipulation;
  /* Colour / icon / link / media popovers hang outside this box. */
  overflow: visible;
}

.sn-eb-wrap { position: relative; display: inline-flex; overflow: visible; }

/* Formatting is a group so a very narrow phone can wrap it without a
   desktop-sized second slab (see the coarse / 719 blocks below). */
.sn-eb-group { display: inline-flex; align-items: center; gap: 2px; }
.sn-eb-format { border-left: 1px solid rgba(250, 243, 227, 0.25); padding-left: 3px; margin-left: 2px; }

.sn-pill {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 18ch;
  min-height: 28px;
  padding: 2px 8px 2px 6px;
  margin: 0 1px;
  border-radius: 999px;
  background: var(--cream);
  border: 1px solid var(--line);
  color: var(--ink);
  text-decoration: none;
  vertical-align: middle;
  line-height: 1.2;
  font-size: 0.82em;
  cursor: pointer;
}
.sn-pill-icon {
  width: 12px;
  height: 12px;
  flex: none;
  opacity: 0.7;
}
.sn-pill-icon svg { width: 100%; height: 100%; display: block; }
.sn-pill-text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 18ch;
}

.sn-linkpop,
.sn-eb-linkpop {
  z-index: 48;
  display: flex;
  flex-direction: column;
  gap: 8px;
  min-width: min(260px, calc(100vw - 24px));
  padding: 10px;
  border-radius: 14px;
  background: var(--ink);
  color: var(--cream);
  box-shadow: 0 6px 18px rgba(28, 28, 28, 0.28);
}
.sn-eb-linkpop {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
}
.sn-eb-mediapop {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
}
.sn-media-error {
  margin: 0;
  color: #ffb4b4;
  font-family: var(--mono);
  font-size: 0.68rem;
}
.sn-link-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  opacity: 0.8;
}
.sn-link-field input,
.sn-link-field select {
  font-family: var(--font);
  font-size: 16px;
  text-transform: none;
  letter-spacing: 0;
  opacity: 1;
  border: 1.5px solid rgba(250, 243, 227, 0.35);
  background: transparent;
  color: var(--cream);
  border-radius: 8px;
  padding: 7px 9px;
  min-height: 36px;
}
.sn-link-field select {
  appearance: auto;
  color-scheme: dark;
}
.sn-link-field input:focus,
.sn-link-field select:focus { outline: none; border-color: var(--cream); }
.sn-link-actions { display: flex; gap: 6px; justify-content: flex-end; }
.sn-link-actions .sn-btn { min-height: 32px; padding: 6px 10px; }

.sn-table-pane {
  flex: 1;
  min-width: 0;
  min-height: 0;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  overflow: auto;
}
.sn-table-root { min-height: 100%; }

/* ---------------------------------------------------------------- collection wiki */

.sn-wiki-pane {
  flex: 1;
  min-width: 0;
  min-height: 0;
  display: flex;
  flex-direction: column;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  overflow: hidden;
}
.sn-wiki-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 8px 12px;
  border-bottom: 1.5px solid var(--line);
  background: var(--cream);
}
.sn-wiki-back {
  flex: none;
  width: 36px;
  height: 36px;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-size: 1.6rem;
  line-height: 1;
  cursor: pointer;
  border-radius: 8px;
}
.sn-wiki-back:hover { background: rgba(28, 28, 28, 0.06); }
.sn-wiki-title {
  flex: 1;
  min-width: 0;
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.25rem;
  font-weight: 600;
  text-align: left;
  cursor: pointer;
  padding: 4px 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sn-wiki-title:hover { text-decoration: underline; }
.sn-wiki-notes-toggle {
  display: none;
  flex: none;
  border: 1.5px solid var(--line);
  background: var(--panel);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  border-radius: var(--sn-radius);
  padding: 6px 12px;
  min-height: 32px;
  cursor: pointer;
}
.sn-wiki-layout {
  flex: 1;
  min-height: 0;
  display: flex;
}
.sn-wiki-outline {
  width: 240px;
  flex: none;
  overflow: auto;
  border-right: 1.5px solid var(--line);
  padding: 12px;
  background: var(--cream);
}
.sn-wiki-outline-label,
.sn-wiki-toc-label {
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  margin: 0 0 10px;
}
.sn-wiki-outline-empty {
  font-size: 0.82rem;
  color: var(--muted);
  margin: 0;
}
.sn-wiki-note {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 8px;
  padding: 8px 0;
  border-bottom: 1px solid var(--line);
}
.sn-wiki-note-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-top: 5px;
  flex: none;
  border: 1px solid rgba(28, 28, 28, 0.15);
}
.sn-wiki-note-body { flex: 1; min-width: 0; }
.sn-wiki-note-text {
  margin: 0;
  font-size: 0.85rem;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.sn-wiki-note-meta {
  margin: 2px 0 0;
  font-family: var(--mono);
  font-size: 0.58rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: var(--muted);
}
.sn-wiki-note-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  width: 100%;
  padding-left: 18px;
}
.sn-wiki-note-btn {
  border: 1.5px solid var(--line);
  background: var(--panel);
  color: var(--ink);
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-radius: var(--sn-radius);
  padding: 5px 10px;
  min-height: 28px;
  cursor: pointer;
}
.sn-wiki-note-btn:hover { background: var(--ink); color: var(--cream); }
.sn-wiki-page {
  flex: 1;
  min-width: 0;
  overflow: auto;
  padding: 20px 28px 80px;
}
.sn-wiki-toc { margin: 0 0 18px; }
.sn-wiki-toc-list {
  margin: 0;
  padding: 0 0 0 18px;
}
.sn-wiki-toc-link {
  border: 0;
  background: none;
  color: var(--ink);
  font: inherit;
  cursor: pointer;
  padding: 2px 0;
  text-align: left;
}
.sn-wiki-toc-link:hover { text-decoration: underline; }
.sn-wiki-toc-link.is-h2 { color: var(--muted); }
.sn-wiki-draft { margin-bottom: 14px; }
.sn-wiki-editor {
  min-height: 40vh;
  outline: none;
  font-size: 1rem;
  line-height: 1.55;
}
.sn-wiki-editor h1 {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.7rem;
  font-weight: 650;
  margin: 0.6em 0 0.35em;
}
.sn-wiki-editor h2 {
  font-family: 'Fraunces', Georgia, serif;
  font-size: 1.25rem;
  font-weight: 600;
  margin: 0.8em 0 0.3em;
}
.sn-wiki-editor hr {
  border: 0;
  border-top: 1.5px solid var(--line);
  margin: 1.1em 0;
}
.sn-wiki-editor ul,
.sn-wiki-editor ol { margin: 0.3em 0; padding-left: 1.3em; }
.sn-wiki-editor div { min-height: 1.3em; }
.sn-wiki-src {
  display: inline-block;
  margin-left: 8px;
  padding: 1px 7px;
  border-radius: var(--sn-radius);
  background: var(--cream);
  border: 1px solid var(--line);
  font-family: var(--mono);
  font-size: 0.58rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  vertical-align: middle;
  user-select: none;
}
.sn-wiki-format {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: 12px;
  z-index: 46;
  display: flex;
  align-items: center;
  gap: 2px;
  background: var(--ink);
  color: var(--cream);
  border-radius: 12px;
  padding: 4px;
  max-width: calc(100vw - 16px);
}
.sn-wiki-format .sn-eb-btn { color: var(--cream); }
.sn-mem-toolbar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 10px;
  padding: 0 0 4px;
}
.sn-mem-newcol {
  padding: 4px 10px;
  min-height: 28px;
  font-size: 0.62rem;
  letter-spacing: 0.04em;
  border-color: var(--line);
}
.sn-mem-newcol-hint {
  font-family: var(--mono);
  font-size: 0.62rem;
  line-height: 1.4;
  color: var(--muted);
  max-width: 28ch;
}

@media (min-width: 1100px) {
  .sn-wiki-pane { border-radius: 10px; }
}

@media (max-width: 1099px) {
  html.sn-wiki-open .sn-toolbar { display: none; }
  html.sn-wiki-open .sn-wiki-pane {
    position: absolute;
    inset: 0;
    z-index: 8;
    border-radius: 0;
    border: 0;
  }
  html.sn-wiki-open .sn-workspace { position: relative; }
  .sn-wiki-notes-toggle { display: inline-flex; }
  .sn-wiki-outline {
    display: none;
    position: absolute;
    inset: 52px 0 0;
    width: auto;
    z-index: 9;
    border-right: 0;
    border-top: 1.5px solid var(--line);
  }
  .sn-wiki-pane.is-drawer .sn-wiki-outline { display: block; }
  .sn-wiki-page { padding: 16px 16px 96px; }
}

.sn-tbl {
  width: 100%;
  border-collapse: collapse;
}
.sn-tbl th {
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1.5px solid var(--line);
  color: var(--muted);
  position: sticky;
  top: 0;
  background: var(--panel);
  z-index: 1;
}
.sn-tbl td {
  padding: 8px 12px;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
  font-size: 0.88rem;
}
.sn-tbl-grouprow th {
  position: static;
  padding: 10px 12px 2px;
  border-bottom: 0;
  background: transparent;
  font-weight: inherit;
  text-transform: none;
  letter-spacing: inherit;
  color: inherit;
  z-index: auto;
}
.sn-tbl-grouprow:first-child th { padding-top: 6px; }
.sn-tbl-group {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
  line-height: 1.2;
  white-space: nowrap;
}
.sn-tbl-row:hover { background: rgba(28, 28, 28, 0.025); }
.sn-tbl-preview-head,
.sn-tbl-preview {
  width: 52px;
  padding-left: 12px;
  padding-right: 4px;
}
.sn-tbl-preview-head {
  padding-right: 4px;
}
.sn-tbl-preview-empty {
  display: block;
  width: 44px;
}
.sn-tbl-thumb-link,
.sn-tbl-thumb-ph {
  display: block;
  width: 44px;
  height: 44px;
  border-radius: 6px;
  overflow: hidden;
  border: 1.5px solid rgba(28, 28, 28, 0.35);
  background: var(--cream);
}
.sn-tbl-thumb-link {
  position: relative;
  color: inherit;
  text-decoration: none;
}
.sn-tbl-thumb-img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.sn-tbl-thumb-ph {
  display: grid;
  place-items: center;
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 500;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  background:
    repeating-linear-gradient(-45deg, transparent 0 8px, rgba(28, 28, 28, 0.035) 8px 16px);
}
.sn-tbl-thumb-play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(28, 28, 28, 0.18);
  pointer-events: none;
}
.sn-tbl-thumb-play::after {
  content: "";
  border-left: 9px solid var(--cream);
  border-top: 6px solid transparent;
  border-bottom: 6px solid transparent;
  margin-left: 3px;
  filter: drop-shadow(0 1px 2px rgba(28, 28, 28, 0.35));
}
.sn-tbl-row .sn-tbl-actions { opacity: 0; }
.sn-tbl-row:hover .sn-tbl-actions,
.sn-tbl-row:focus-within .sn-tbl-actions,
.sn-tbl-row.is-open .sn-tbl-actions { opacity: 1; }
.sn-tbl-body {
  min-height: 28px;
  max-width: 42rem;
  font-size: 16px;
}
.sn-tbl-body.is-editing,
.sn-tbl-body[contenteditable="true"] {
  outline: 1.5px solid var(--ink);
  border-radius: 6px;
  padding: 4px 6px;
  background: var(--panel);
}
.sn-tbl-body ul,
.sn-tbl-body ol,
.sn-mem-text ul,
.sn-mem-text ol {
  margin: 0.15em 0;
  padding-left: 1.2em;
}
.sn-tbl-body > div,
.sn-mem-text > div { min-height: 1.3em; }
.sn-tbl-meta {
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--muted);
  white-space: nowrap;
}
.sn-tbl-icon,
.sn-tbl-pin {
  width: 28px;
  opacity: 0.7;
}
.sn-tbl-icon svg,
.sn-tbl-pin svg { width: 16px; height: 16px; display: block; }
.sn-tbl-icon .sn-custom-icon-image { width: 16px; height: 16px; }
.sn-tbl-empty {
  display: grid;
  place-content: center;
  place-items: center;
  gap: 14px;
  min-height: 40vh;
  text-align: center;
  padding: 32px 16px;
}
.sn-tbl-empty .sn-btn { pointer-events: auto; }

@media (min-width: 720px) {
  .sn-tbl-list { display: none; }
}
@media (max-width: 719px) {
  .sn-tbl { display: none; }
  /* Phone list: stacked colour-filled cards, not a leftover desktop table. */
  .sn-table-pane {
    border: 0;
    border-radius: 0;
    background: transparent;
  }
  .sn-tbl-list {
    display: flex;
    flex-direction: column;
    gap: 8px;
    padding: 0 0 20px;
  }
  .sn-tbl-list .sn-tbl-card {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    flex-wrap: nowrap;
    gap: 4px;
    padding: 12px 12px 10px;
    border: 1.5px solid var(--line);
    border-radius: 8px;
    background: var(--note-fill, var(--panel));
    min-height: 0;
  }
  .sn-tbl-list .sn-tbl-card:hover { background: var(--note-fill, var(--panel)); }
  .sn-tbl-list .sn-tbl-card-lead {
    display: flex;
    align-items: flex-start;
    gap: 8px;
    min-width: 0;
  }
  .sn-tbl-list .sn-tbl-preview {
    width: auto;
    padding: 0;
    flex-shrink: 0;
  }
  .sn-tbl-list .sn-tbl-preview[hidden] { display: none; }
  .sn-tbl-list .sn-mem-icon { width: 16px; height: 16px; flex-shrink: 0; }
  .sn-tbl-list .sn-mem-icon:empty { display: none; }
  .sn-tbl-list .sn-tbl-body {
    max-width: none;
    min-height: 1.4em;
    -webkit-line-clamp: unset;
    display: block;
    /* Beat .sn-mem-text's 0.82rem so iOS does not zoom the page on edit. */
    font-size: 16px;
  }
  .sn-tbl-list .sn-mem-meta { max-width: none; }
  .sn-tbl-list .sn-tbl-actions {
    margin-left: 0;
    justify-content: flex-end;
  }
  .sn-tbl-list .sn-tbl-card:not(.is-open) .sn-tbl-actions { display: none; }
}

.sn-eb-btn {
  width: 26px;
  height: 26px;
  padding: 5px;
  border: 0;
  border-radius: 50%;
  background: transparent;
  color: var(--cream);
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 0.8rem;
  line-height: 1;
}
.sn-eb-btn svg { width: 100%; height: 100%; }
.sn-eb-btn:hover { background: rgba(250, 243, 227, 0.18); }
.sn-eb-btn[aria-pressed="true"] { background: var(--cream); color: var(--ink); }
.sn-eb-danger:hover { background: #a02020; color: #fff; }
.sn-eb-done { font-size: 0.85rem; }

.sn-eb-dot {
  width: 14px;
  height: 14px;
  border-radius: 50%;
  border: 1.5px solid currentColor;
  background: transparent;
}

/* Colour and icon are the same gesture: a compact popover over the bar.
   width: max-content so shrink-to-fit does not collapse to the 32 px wrap
   (a column of swatches, then placePopover flips the stack under the keyboard). */
.sn-eb-palette,
.sn-eb-iconpop {
  position: absolute;
  bottom: calc(100% + 8px);
  left: 50%;
  transform: translateX(-50%);
  width: max-content;
  z-index: 48;
  background: var(--ink);
  box-shadow: 0 6px 18px rgba(28, 28, 28, 0.28);
  touch-action: manipulation;
}
/* placePopover overrides top/bottom once it can measure the bar. */

.sn-eb-palette {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  max-width: min(280px, calc(100vw - 24px));
  gap: 4px;
  border-radius: 16px;
  padding: 5px 7px;
}

.sn-eb-iconpop {
  display: grid;
  grid-template-columns: repeat(4, auto);
  gap: 3px;
  border-radius: 12px;
  padding: 6px;
}

.sn-eb-icon {
  width: 28px;
  height: 28px;
  padding: 5px;
  border: 1.5px solid transparent;
  background: transparent;
  color: var(--cream);
  border-radius: 8px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.sn-eb-icon svg { width: 100%; height: 100%; }
.sn-eb-icon:hover { border-color: rgba(250, 243, 227, 0.4); }
.sn-eb-icon[aria-pressed="true"] { background: var(--cream); color: var(--ink); }
.sn-custom-icon-add {
  font-family: var(--mono);
  font-size: 1rem;
  font-weight: 500;
}
.sn-eb-iconpop.has-custom-form,
.sn-ab-iconpop.has-custom-form,
.sn-eb-iconpop.has-name-editor {
  display: block;
  width: min(300px, calc(100vw - 24px));
}
.sn-custom-icon-form {
  display: flex;
  flex-direction: column;
  gap: 7px;
}
.sn-custom-icon-input {
  width: 100%;
  min-height: 36px;
  border: 1.5px solid rgba(250, 243, 227, 0.35);
  border-radius: 8px;
  padding: 7px 9px;
  background: transparent;
  color: var(--cream);
  font-family: var(--font);
  font-size: 16px;
}
.sn-custom-icon-input:focus { outline: none; border-color: var(--cream); }
.sn-custom-icon-input::placeholder { color: rgba(250, 243, 227, 0.62); }
.sn-custom-icon-error {
  color: #ffb4b4;
  font-family: var(--mono);
  font-size: 0.66rem;
}
.sn-custom-icon-actions {
  display: flex;
  justify-content: flex-end;
  gap: 6px;
}
.sn-custom-icon-actions .sn-btn { min-height: 32px; padding: 6px 10px; }
.sn-icon-name-edit {
  grid-column: 1 / -1;
  border: 1px solid rgba(250, 243, 227, 0.35);
  border-radius: 8px;
  padding: 6px 9px;
  background: transparent;
  color: var(--cream);
  font-family: var(--mono);
  font-size: 0.64rem;
  cursor: pointer;
}
.sn-icon-name-edit:hover { background: rgba(250, 243, 227, 0.15); }
.sn-icon-name-editor {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.sn-icon-name-title {
  font-family: var(--mono);
  font-size: 0.66rem;
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}
.sn-icon-name-row {
  display: grid;
  grid-template-columns: 24px minmax(0, 1fr);
  align-items: center;
  gap: 7px;
}
.sn-icon-name-picture {
  display: grid;
  place-items: center;
  width: 24px;
  height: 24px;
}
.sn-icon-name-picture svg { width: 18px; height: 18px; }
.sn-icon-name-input {
  width: 100%;
  min-height: 34px;
  border: 1.5px solid rgba(250, 243, 227, 0.35);
  border-radius: 8px;
  padding: 6px 8px;
  background: transparent;
  color: var(--cream);
  font-family: var(--font);
  font-size: 16px;
}
.sn-icon-name-input:focus { outline: none; border-color: var(--cream); }

.sn-eb-swatch {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  padding: 0;
}
.sn-eb-swatch[aria-pressed="true"] { border-color: var(--cream); }
.sn-eb-swatch.sn-eb-none {
  background: transparent;
  border: 1.5px dashed rgba(250, 243, 227, 0.6);
  color: var(--cream);
}

/* ------------------------------------------- tier 2: the selection bar, docked low */

/* Centred with auto margins rather than left:50% — an absolutely positioned
   box only shrink-wraps to the space on one side of a 50% offset, which made
   the bar wrap onto two rows on a wide canvas. */
.sn-selbar {
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 12px;
  margin: 0 auto;
  width: fit-content;
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 8px;
  max-width: calc(100% - 16px);
  flex-wrap: wrap;
  justify-content: center;
  background: var(--ink);
  color: var(--cream);
  border-radius: var(--sn-radius);
  padding: 6px 12px;
  box-shadow: 0 8px 24px rgba(28, 28, 28, 0.25);
}

.sn-ab-count {
  font-family: var(--mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.7;
  white-space: nowrap;
}

.sn-ab-swatches { display: inline-flex; gap: 5px; }

.sn-ab-swatch {
  width: 18px;
  height: 18px;
  border-radius: 50%;
  border: 2px solid transparent;
  cursor: pointer;
  padding: 0;
}
.sn-ab-swatch[aria-pressed="true"] { border-color: var(--cream); }

.sn-ab-iconwrap { position: relative; display: inline-flex; }

.sn-ab-iconbtn,
.sn-ab-pin {
  border: 1.5px solid rgba(250, 243, 227, 0.4);
  background: transparent;
  color: var(--cream);
  border-radius: var(--sn-radius);
  font-family: var(--mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  padding: 4px 10px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
  min-height: 28px;
}
.sn-ab-iconbtn svg { width: 14px; height: 14px; }
.sn-ab-iconbtn .sn-custom-icon-image { width: 16px; height: 16px; }
.sn-ab-pin[aria-pressed="true"] { background: var(--cream); color: var(--ink); }

.sn-ab-iconpop {
  position: absolute;
  bottom: calc(100% + 10px);
  left: 50%;
  transform: translateX(-50%);
  display: grid;
  grid-template-columns: repeat(6, 1fr);
  gap: 4px;
  background: var(--ink);
  border-radius: 12px;
  padding: 8px;
  box-shadow: 0 8px 24px rgba(28, 28, 28, 0.3);
}

.sn-ab-icongrid {
  width: 30px;
  height: 30px;
  border: 1.5px solid transparent;
  background: transparent;
  color: var(--cream);
  border-radius: 8px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}
.sn-ab-icongrid svg { width: 16px; height: 16px; }
.sn-ab-icongrid .sn-custom-icon-image { width: 18px; height: 18px; }
.sn-ab-icongrid:hover { border-color: rgba(250, 243, 227, 0.4); }
.sn-ab-icongrid[aria-pressed="true"] { background: var(--cream); color: var(--ink); }

/* The collection control says what it is — the model is not guessable. */
.sn-ab-collection { display: inline-flex; align-items: center; flex-wrap: wrap; gap: 6px; min-width: 0; }

.sn-ab-label {
  font-family: var(--mono);
  font-size: 0.6rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  opacity: 0.65;
  white-space: nowrap;
}

.sn-ab-name {
  border: 1.5px solid rgba(250, 243, 227, 0.4);
  background: transparent;
  color: var(--cream);
  border-radius: var(--sn-radius);
  font-family: var(--font);
  font-size: 0.78rem;
  padding: 4px 12px;
  width: 190px;
  max-width: 44vw;
  min-height: 28px;
}
.sn-ab-name::placeholder { color: rgba(250, 243, 227, 0.5); }
.sn-ab-name:focus { outline: none; border-color: var(--cream); }

.sn-ab-page {
  border: 1.5px solid var(--cream);
  background: var(--cream);
  color: var(--ink);
  border-radius: var(--sn-radius);
  font-family: var(--mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 4px 10px;
  cursor: pointer;
  min-height: 28px;
  white-space: nowrap;
}

.sn-ab-file {
  border: 0;
  background: var(--cream);
  color: var(--ink);
  border-radius: var(--sn-radius);
  font-family: var(--mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 6px 14px;
  cursor: pointer;
  min-height: 28px;
}

/* File keeps the notes (memory); Delete does not. It is outlined rather than
   filled so the safe action stays the obvious one. */
.sn-ab-delete {
  border: 1.5px solid rgba(250, 243, 227, 0.4);
  background: transparent;
  color: var(--cream);
  border-radius: var(--sn-radius);
  font-family: var(--mono);
  font-size: 0.64rem;
  text-transform: uppercase;
  letter-spacing: 0.05em;
  padding: 6px 14px;
  cursor: pointer;
  min-height: 28px;
}
.sn-ab-delete:hover { background: #c23434; border-color: #c23434; color: #fff; }

.sn-ab-hint {
  flex-basis: 100%;
  text-align: center;
  font-family: var(--mono);
  font-size: 0.6rem;
  letter-spacing: 0.03em;
  opacity: 0.7;
}

/* ---------------------------------------------------------------- memory sidebar */

.sn-sidebar {
  display: flex;
  flex-direction: column;
  flex: none;
  width: 100%;
  min-height: 0;
  border: 1.5px solid var(--line);
  border-radius: 12px;
  background: var(--panel);
  overflow: hidden;
}

.sn-side-head { display: none; }

.sn-memory {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 12px 14px 20px;
}

.sn-mem-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  margin-bottom: 8px;
}

.sn-mem-search {
  border: 1.5px solid var(--line);
  border-radius: var(--sn-radius);
  background: var(--panel);
  font-family: var(--font);
  font-size: 0.88rem;
  padding: 9px 14px;
  flex: 1;
  min-width: 180px;
  min-height: 40px;
}
.sn-mem-search:focus { outline: none; border-color: var(--ink); }

/* Chip rows scroll sideways rather than stacking into a wall on a phone. */
.sn-mem-chiprow {
  display: flex;
  gap: 5px;
  flex-wrap: wrap;
}

.sn-mem-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border: 1.5px solid var(--line);
  border-radius: var(--sn-radius);
  background: var(--panel);
  color: var(--ink);
  padding: 5px 10px;
  cursor: pointer;
  opacity: 0.75;
  white-space: nowrap;
  flex: none;
}
.sn-mem-chip:hover { opacity: 1; }
.sn-mem-chip[aria-pressed="true"] { border-color: var(--ink); opacity: 1; }

.sn-mem-select {
  border: 1.5px solid var(--line);
  border-radius: var(--sn-radius);
  background: var(--panel);
  font-family: var(--mono);
  font-size: 0.68rem;
  text-transform: uppercase;
  padding: 8px 12px;
  min-height: 40px;
  max-width: 100%;
}

.sn-mem-note {
  font-family: var(--mono);
  font-size: 0.62rem;
  line-height: 1.6;
  color: var(--muted);
  margin: 0 0 8px;
}
.sn-mem-note b { color: var(--ink); font-weight: 500; }

.sn-mem-list { border-top: 1.5px solid var(--line); }

.sn-mem-collection { margin: 0; }

.sn-mem-colhead,
.sn-tbl-listhead {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  padding: 8px 2px 3px;
  border-bottom: 0;
}

.sn-mem-colhead-main {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px 8px;
  min-width: 0;
  flex: 1 1 auto;
}

.sn-mem-colname {
  font-family: var(--mono);
  font-size: 0.62rem;
  font-weight: 500;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}
.sn-mem-loose .sn-mem-colname { opacity: 1; }

.sn-mem-row {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: 6px;
  padding: 3px 2px;
  border-bottom: 1px solid var(--line);
}
.sn-mem-list .sn-mem-row {
  user-select: none;
  touch-action: pan-y;
  cursor: grab;
}
.sn-mem-list .sn-mem-row.is-dragging { cursor: grabbing; opacity: 0.45; }
.sn-mem-row.is-open { flex-wrap: wrap; }
.sn-mem-row:hover { background: rgba(28, 28, 28, 0.025); }

.sn-mem-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  border: 1px solid var(--line);
  flex: none;
}

.sn-mem-icon { width: 15px; height: 15px; flex: none; opacity: 0.65; }
.sn-mem-icon svg { width: 100%; height: 100%; }
.sn-mem-icon:empty { visibility: hidden; }

.sn-mem-text {
  flex: 0 1 auto;
  min-width: 0;
  font-size: 0.82rem;
  overflow: hidden;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
}
.sn-mem-list .sn-mem-text {
  display: block;
  white-space: nowrap;
  text-overflow: ellipsis;
  -webkit-line-clamp: unset;
  -webkit-box-orient: unset;
}
.sn-mem-list .sn-mem-text > :not(:first-child) { display: none; }
.sn-mem-list .sn-mem-text > div { min-height: 0; }

.sn-mem-meta {
  font-family: var(--mono);
  font-size: 0.62rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 140px;
  flex: none;
}
.sn-mem-meta a { color: inherit; }

.sn-mem-actions { display: inline-flex; gap: 2px; flex: none; margin-left: auto; }
.sn-mem-colhead .sn-mem-actions { margin-left: auto; }

/* Page is the way into the wiki — keep it on the collection name, not in a
   hover-only or overflow cluster. Loose notes never get one. */
.sn-mem-page {
  opacity: 1;
  border: 1.5px solid var(--ink);
  background: var(--ink);
  color: var(--cream);
  padding: 5px 10px;
  letter-spacing: 0.05em;
}
.sn-mem-page:hover { opacity: 1; background: var(--ink); filter: brightness(1.08); }

/* Actions stay out of the way until the row is wanted. */
.sn-mem-row .sn-mem-actions { opacity: 0; }
.sn-mem-row:hover .sn-mem-actions,
.sn-mem-row:focus-within .sn-mem-actions,
.sn-mem-row.is-open .sn-mem-actions { opacity: 1; }

.sn-mem-action {
  border: 0;
  background: transparent;
  color: var(--ink);
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding: 6px 8px;
  cursor: pointer;
  opacity: 0.55;
  border-radius: 6px;
}
.sn-mem-action:hover { opacity: 1; background: rgba(28, 28, 28, 0.05); }
.sn-mem-danger:hover { color: #a02020; }

.sn-mem-empty {
  font-family: var(--mono);
  font-size: 0.78rem;
  line-height: 1.7;
  color: var(--muted);
  padding: 28px 4px;
  text-align: center;
}

.sn-mem-more { text-align: center; padding: 16px 0; }

.sn-restore-ghost {
  position: fixed;
  z-index: 80;
  pointer-events: none;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  max-width: 220px;
  padding: 5px 10px;
  border: 1.5px solid var(--line);
  border-radius: var(--sn-radius);
  background: var(--panel);
  box-shadow: 0 8px 20px rgba(28, 28, 28, 0.12);
  font-family: var(--mono);
  font-size: 0.68rem;
  color: var(--ink);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  transform: translate(-12px, -14px);
}
.sn-restore-ghost.is-over { border-color: var(--ink); }

/* ---------------------------------------------------------------- guide + sheet */

.sn-scrim {
  position: fixed;
  inset: 0;
  z-index: 55;
  background: rgba(28, 28, 28, 0.35);
}

/* ---------------------------------------------------------------- sign in */

.sn-auth-pane {
  position: fixed;
  z-index: 60;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: calc(var(--nav-h) + 16px) 16px 24px;
  pointer-events: none;
}

.sn-auth-card {
  pointer-events: auto;
  width: min(400px, 100%);
  max-height: min(88vh, 680px);
  overflow-y: auto;
  overscroll-behavior: contain;
  background: var(--panel);
  border: 1.5px solid var(--ink);
  border-radius: 14px;
  box-shadow: 0 16px 40px rgba(28, 28, 28, 0.28);
  padding: 24px 22px 20px;
}

.sn-auth-close {
  position: absolute;
  top: calc(var(--nav-h) + 12px);
  right: 16px;
  z-index: 61;
  width: 44px;
  height: 44px;
  border: 1.5px solid var(--ink);
  border-radius: 10px;
  background: var(--panel);
  color: var(--ink);
  font-size: 1.4rem;
  line-height: 1;
  cursor: pointer;
}

.sn-auth-close:hover { background: var(--ink); color: var(--cream); }

.sn-auth-title {
  font-family: var(--display);
  font-size: 1.35rem;
  margin: 0 0 8px;
}

.sn-auth-copy {
  font-size: 0.88rem;
  color: var(--muted);
  line-height: 1.55;
  margin: 0 0 18px;
}

.sn-auth-note {
  font-size: 0.82rem;
  font-weight: 700;
  color: var(--ink);
  background: #fde8e8;
  border: 1.5px solid #c44;
  border-radius: var(--sn-radius);
  padding: 8px 12px;
  margin: 0 0 16px;
}

.sn-auth-small {
  font-size: 0.76rem;
  color: var(--muted);
  margin: 12px 0 0;
  line-height: 1.45;
}

.sn-auth-small a { color: var(--ink); }

.sn-auth-form { text-align: left; }

.sn-auth-tabs {
  display: flex;
  border: 1.5px solid var(--ink);
  border-radius: var(--sn-radius);
  overflow: hidden;
  margin-bottom: 14px;
}

.sn-auth-tab {
  flex: 1;
  border: none;
  background: transparent;
  color: var(--muted);
  font: inherit;
  font-size: 0.82rem;
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 10px 8px;
  cursor: pointer;
}

.sn-auth-tab.is-active {
  background: var(--ink);
  color: var(--cream);
}

.sn-auth-body {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.sn-auth-body.is-hidden { display: none; }

.sn-auth-field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 0.78rem;
  font-weight: 600;
  letter-spacing: 0.03em;
  text-transform: uppercase;
}

.sn-auth-input {
  font: inherit;
  font-size: 1rem;
  border: 1.5px solid var(--ink);
  border-radius: var(--sn-radius);
  background: var(--cream);
  color: var(--ink);
  padding: 10px 12px;
  min-height: 44px;
}

.sn-auth-submit {
  width: 100%;
  margin-top: 4px;
  min-height: 44px;
}

.sn-auth-error {
  font-size: 0.82rem;
  color: #a22;
  margin: 8px 0 0;
}

.sn-guide,
.sn-sheet {
  position: fixed;
  z-index: 60;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1.5px solid var(--ink);
  border-radius: 14px;
  box-shadow: 0 16px 40px rgba(28, 28, 28, 0.28);
  width: min(380px, calc(100vw - 24px));
  max-height: min(72vh, 620px);
  overflow: hidden;
}

.sn-guide-head,
.sn-sheet-head {
  flex: none;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 12px 14px 8px 16px;
  border-bottom: 1.5px solid var(--line);
}

.sn-guide-title,
.sn-sheet-title {
  font-family: var(--display);
  font-size: 1.05rem;
  margin: 0;
}

.sn-guide-close {
  border: 0;
  background: transparent;
  color: var(--ink);
  font-size: 1.4rem;
  line-height: 1;
  width: 40px;
  height: 40px;
  flex: none;
  border-radius: 50%;
  cursor: pointer;
}
.sn-guide-close:hover { background: rgba(28, 28, 28, 0.07); }

.sn-guide-body,
.sn-sheet-body {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 12px 16px 16px;
}

.sn-guide-group + .sn-guide-group { margin-top: 16px; }

.sn-guide-grouptitle {
  font-family: var(--mono);
  font-size: 0.62rem;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--muted);
  margin: 0 0 8px;
}

.sn-guide-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 6px 0;
}

.sn-guide-glyph {
  flex: none;
  width: 28px;
  height: 28px;
  border: 1.5px solid var(--line);
  border-radius: 8px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--mono);
  font-size: 0.72rem;
  background: var(--cream);
}
.sn-guide-glyph svg { width: 15px; height: 15px; }

.sn-guide-text { font-size: 0.85rem; line-height: 1.45; }
.sn-guide-text b { font-weight: 600; }
.sn-guide-text span { display: block; color: var(--muted); font-size: 0.8rem; }

.sn-guide-foot {
  flex: none;
  padding: 10px 16px 14px;
  border-top: 1.5px solid var(--line);
}

/* The sheet is a centred dialog on web and a bottom sheet on phones. */
.sn-sheet { top: 50%; left: 50%; transform: translate(-50%, -50%); }

.sn-sheet-body .sn-menu-item {
  width: 100%;
  border: 1.5px solid var(--line);
  margin-bottom: 6px;
  text-transform: none;
  font-family: var(--font);
  font-size: 0.9rem;
  letter-spacing: 0;
}
.sn-sheet-body .sn-menu-item[aria-pressed="true"] { border-color: var(--ink); background: var(--cream); }

.sn-sheet-form { display: flex; gap: 8px; margin-top: 12px; }
.sn-sheet-form .sn-mem-search { flex: 1; min-width: 0; }

/* ---------------------------------------------------------------- toast */

.sn-toast {
  position: fixed;
  left: 50%;
  bottom: calc(24px + env(safe-area-inset-bottom, 0px));
  transform: translateX(-50%) translateY(120%);
  background: var(--ink);
  color: var(--cream);
  font-family: var(--mono);
  font-size: 0.72rem;
  letter-spacing: 0.04em;
  padding: 10px 16px;
  border-radius: var(--sn-radius);
  opacity: 0;
  transition: transform 180ms ease, opacity 180ms ease;
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 12px;
  max-width: calc(100vw - 24px);
  /* A faded-out toast must never swallow clicks meant for the page. */
  pointer-events: none;
}
.sn-toast.is-visible { transform: translateX(-50%) translateY(0); opacity: 1; pointer-events: auto; }

.sn-toast button {
  border: 1.5px solid rgba(250, 243, 227, 0.5);
  background: transparent;
  color: var(--cream);
  border-radius: var(--sn-radius);
  font: inherit;
  text-transform: uppercase;
  padding: 5px 14px;
  min-height: 32px;
  cursor: pointer;
  flex: none;
}
.sn-toast button:hover { background: var(--cream); color: var(--ink); }

/* ---------------------------------------------------------------- breakpoints */

/* Wide: memory lives beside the board, so the tabs have nothing to switch. */
@media (min-width: 1100px) {
  :root { --file-x: 120px; --file-y: 0px; }

  .sn-tabs { display: none; }

  .sn-sidebar { width: 320px; }
  .sn-sidebar.is-collapsed { width: 42px; }

  .sn-side-head {
    flex: none;
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 8px 8px 14px;
    border-bottom: 1.5px solid var(--line);
    background: var(--cream);
  }

  .sn-side-title {
    font-family: var(--mono);
    font-size: 0.66rem;
    text-transform: uppercase;
    letter-spacing: 0.08em;
  }

  .sn-side-count {
    font-family: var(--mono);
    font-size: 0.6rem;
    background: var(--ink);
    color: var(--cream);
    border-radius: var(--sn-radius);
    padding: 1px 7px;
  }
  .sn-side-count:empty { display: none; }

  .sn-side-toggle {
    margin-left: auto;
    border: 1.5px solid var(--line);
    background: var(--panel);
    color: var(--ink);
    border-radius: 50%;
    width: 26px;
    height: 26px;
    flex: none;
    cursor: pointer;
    line-height: 1;
  }
  .sn-side-toggle:hover { background: var(--ink); color: var(--cream); }

  .sn-sidebar.is-collapsed .sn-side-head {
    flex-direction: column;
    padding: 8px 6px;
    gap: 10px;
    height: 100%;
    border-bottom: 0;
    align-items: center;
  }
  .sn-sidebar.is-collapsed .sn-side-title { writing-mode: vertical-rl; letter-spacing: 0.14em; }
  .sn-sidebar.is-collapsed .sn-side-toggle { margin-left: 0; transform: rotate(180deg); }
}

/* Narrow: the ⋯ menu carries what the toolbar cannot. */
@media (max-width: 1099px) {
  .sn-wide-only { display: none; }
}
@media (min-width: 1100px) {
  .sn-narrow-only { display: none; }
  .sn-more { display: none; }
}

@media (max-width: 719px) {
  .sn-app { padding: 8px 8px 10px; gap: 8px; }
  .sn-viewport { border-radius: 10px; }
  .sn-sidebar { border-radius: 10px; }
  .sn-memory { padding: 10px 10px 24px; }

  .sn-nav {
    --nav-h: calc(3.75rem + env(safe-area-inset-top, 0px));
    height: auto;
    padding-left: 12px;
    padding-right: 12px;
    padding-top: calc(4px + env(safe-area-inset-top, 0px));
    padding-bottom: 4px;
  }
  .sn-nav-logo,
  .sn-nav-section {
    min-height: 44px;
  }
  .sn-nav-logo { font-size: 0.78rem; }
  .sn-nav-links { font-size: 0.72rem; }
  .sn-nav-section span { display: none; }
  .sn-nav-links a { padding: 0 10px; min-height: 44px; }
  .sn-navchip { padding: 8px 10px; min-height: 44px; }

  /* Rounded rectangles, not capsules — note cards stay 10px on their own. */
  .sn-tab,
  .sn-tab-count,
  .sn-btn,
  .sn-iconbtn,
  .sn-view-toggle {
    border-radius: 8px;
  }

  /* Two rows on a phone: the sentence, then the way out of it. */
  .sn-guestbar {
    margin: 6px 6px 0;
    flex-wrap: wrap;
    row-gap: 8px;
    border-radius: 12px;
    padding: 8px 8px 8px 12px;
    font-size: 0.64rem;
    line-height: 1.5;
  }
  .sn-guestbar-text { flex: 1 1 100%; }
  .sn-guestbar-cta { margin-left: 0; }
  .sn-guestbar-close { margin-left: auto; }

  /* Two rows, not eight-across: tabs (+ ?) then the board actions.
     Desktop above this breakpoint stays a single left-aligned row. */
  .sn-toolbar {
    flex-wrap: wrap;
    gap: 10px;
    align-items: center;
  }
  .sn-tabs {
    flex: 1 1 auto;
    gap: 8px;
    min-width: 0;
    order: 1;
  }
  .sn-tab {
    flex: 1 1 0;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-height: 44px;
    padding: 10px 14px;
    font-size: 0.78rem;
  }
  #board-help {
    order: 2;
    width: 44px;
    height: 44px;
    min-height: 44px;
  }
  .sn-toolbar-actions {
    order: 3;
    flex: 1 1 100%;
    gap: 10px;
  }
  .sn-toolbar-actions:not(:has(#board-actions:not([hidden]))) {
    display: none;
  }
  .sn-board-actions {
    gap: 10px;
    justify-content: flex-start;
  }
  .sn-view-toggle button { width: 44px; height: 44px; }
  .sn-btn-label { display: none; }
  .sn-btn-pen {
    width: 44px;
    height: 44px;
    min-height: 44px;
    padding: 0;
    justify-content: center;
  }
  .sn-iconbtn,
  .sn-btn.sn-btn-add {
    width: 44px;
    height: 44px;
    min-height: 44px;
  }
  .sn-zoom { display: none; }

  .sn-mem-chiprow {
    flex-wrap: nowrap;
    overflow-x: auto;
    scrollbar-width: none;
    padding-bottom: 2px;
    max-width: 100%;
  }
  .sn-mem-chiprow::-webkit-scrollbar { display: none; }
  .sn-mem-meta { max-width: 100%; }
  .sn-mem-row .sn-mem-actions { opacity: 1; }
  /* Tap a row to reveal its actions instead of hovering. */
  .sn-mem-row:not(.is-open) .sn-mem-actions { display: none; }
  .sn-mem-row.is-open { background: rgba(28, 28, 28, 0.04); }
  .sn-mem-row.is-open .sn-mem-actions { width: 100%; margin-left: 0; justify-content: flex-end; }
  .sn-tbl-row .sn-tbl-actions { opacity: 1; }
  .sn-tbl-row:not(.is-open) .sn-tbl-actions { display: none; }

  .sn-selbar {
    bottom: calc(8px + env(safe-area-inset-bottom, 0px));
    width: auto;
    max-width: none;
    border-radius: 12px;
    padding: 8px 10px;
    row-gap: 8px;
  }
  .sn-ab-name { width: 100%; max-width: none; }
  .sn-ab-collection { flex: 1 1 100%; }

  /* Guide and pickers arrive as bottom sheets. */
  .sn-guide,
  .sn-sheet {
    left: 0;
    right: 0;
    bottom: 0;
    top: auto;
    width: auto;
    max-height: 82dvh;
    border-radius: 18px 18px 0 0;
    border-bottom: 0;
    transform: none;
  }
  .sn-guide-body,
  .sn-sheet-body { padding-bottom: calc(20px + env(safe-area-inset-bottom, 0px)); }
  .sn-guide-foot { padding-bottom: calc(14px + env(safe-area-inset-bottom, 0px)); }

  .sn-hintstrip {
    left: 8px;
    right: 8px;
    transform: none;
    max-width: none;
    border-radius: 14px;
  }
}

/* Fingers need bigger targets than a cursor does. */
@media (pointer: coarse) {
  .sn-eb-btn { width: 44px; height: 44px; padding: 11px; }
  .sn-eb-swatch { width: 32px; height: 32px; }
  .sn-eb-palette { gap: 6px; padding: 7px 9px; }
  .sn-eb-icon { width: 44px; height: 44px; padding: 12px; }
  .sn-eb-iconpop { grid-template-columns: repeat(4, 44px); gap: 4px; }
  /* A tablet fits nine 44 px targets on one row. Phones use the compact
     block below — do not force a second fat row here. */
  .sn-ab-swatch { width: 28px; height: 28px; }
  .sn-ab-iconbtn,
  .sn-ab-pin,
  .sn-ab-page,
  .sn-ab-file,
  .sn-ab-delete,
  .sn-ab-name,
  .sn-mem-action,
  .sn-mem-page { min-height: 44px; }
  .sn-mem-action { padding: 9px 12px; }
  .sn-mem-row { min-height: 44px; padding: 8px 2px; }
  .sn-ab-icongrid { width: 40px; height: 40px; }
  /* Connector dots and the 14px hover grip are mouse affordances. Touch
     resize is a 44px handle on the selected/editing card, not hover — on a
     tablet as much as a phone, since neither has a pointer to hover with. */
  .sn-dot,
  .sn-card-resize { display: none; }

  /* A finger that lands on a preview is almost always trying to move the note,
     and a link under the whole picture turns every one of those into a trip to
     another site. On touch the preview is inert — presses fall through to the
     board's drag/tap machinery — and the corner chip is the way out to the
     source. Video keeps its centre glyph so the rest of the still still drags. */
  .sn-media-link,
  .sn-media-play { pointer-events: none; }
  .sn-media-play-glyph {
    pointer-events: auto;
    width: 44px;
    height: 44px;
  }
  .sn-media-play-glyph::after { left: 17px; top: 13px; }
  .sn-media-open { display: inline-flex; }

  .sn-card.is-selected .sn-card-resize,
  .sn-card.is-editing .sn-card-resize {
    display: block;
    width: 44px;
    height: 44px;
    opacity: 1;
    right: 2px;
    bottom: 2px;
    border-radius: 8px;
    background-color: rgba(255, 252, 245, 0.92);
    background-image:
      linear-gradient(135deg, transparent 52%, rgba(28, 28, 28, 0.5) 52%, rgba(28, 28, 28, 0.5) 58%, transparent 58%,
        transparent 66%, rgba(28, 28, 28, 0.5) 66%, rgba(28, 28, 28, 0.5) 72%, transparent 72%);
    box-shadow: inset 0 0 0 1.5px rgba(28, 28, 28, 0.28);
    z-index: 8;
    /* The handle owns the finger on it: no page pan, no double-tap zoom. */
    touch-action: none;
    user-select: none;
    -webkit-user-select: none;
    cursor: nwse-resize;
  }

  /* iOS Safari zooms the whole document when focus lands on editable text
     smaller than 16 px, and the page never zooms back. Everything you can type
     into is therefore at least 16 px on touch: the note body, board ink, the
     collection name, the memory filters, and the table Note cell (including
     the <720 grouped list, whose .sn-mem-text would otherwise win at 0.82rem).
     Board pan and pinch are unaffected — they are canvas transforms, not page
     scale. */
  .sn-card-body,
  .sn-compose-body,
  .sn-ink,
  .sn-ab-name,
  .sn-mem-search,
  .sn-mem-select,
  .sn-wiki-editor,
  .sn-wiki-title,
  .sn-link-field input,
  .sn-tbl-body,
  .sn-tbl-list .sn-mem-text { font-size: 16px; }
  .sn-wiki-note-btn,
  .sn-wiki-notes-toggle,
  .sn-wiki-back { min-height: 44px; }
  .sn-wiki-back { width: 44px; }
  .sn-chip-wiki { min-width: 28px; min-height: 28px; padding: 6px 10px; }
  .sn-ink { font-size: 17px; }

  /* Toolbar targets match the 44 px the note bar uses. */
  .sn-btn,
  .sn-iconbtn,
  .sn-tab,
  .sn-zoom-btn,
  .sn-zoom-label,
  .sn-navchip,
  .sn-nav-install,
  .sn-guestbar-cta,
  .sn-guestbar-close { min-height: 44px; }
  .sn-iconbtn,
  .sn-btn.sn-btn-add { width: 44px; }
  .sn-guestbar-close { width: 44px; }

  /* Buttons outside the (touch-action: none) canvas still need to opt out of
     double-tap zoom. Table chrome is the same: allow scroll, not page zoom. */
  .sn-btn,
  .sn-iconbtn,
  .sn-tab,
  .sn-menu-item,
  .sn-mem-action,
  .sn-mem-page,
  .sn-ab-page,
  .sn-mem-chip,
  .sn-navchip,
  .sn-nav-install,
  .sn-guestbar-cta,
  .sn-guestbar-close,
  .sn-selbar,
  .sn-toast button,
  .sn-table-pane,
  .sn-tbl,
  .sn-tbl-list,
  .sn-tbl-row,
  .sn-tbl-card,
  .sn-tbl-body { touch-action: manipulation; }
  .sn-compose,
  .sn-compose-body { touch-action: manipulation; }
}

/* Phone edit chrome: one slim row of small glyphs, 44 px hits via slop.
   Never a 120 px floating slab over the dotted canvas. */
@media (pointer: coarse) and (max-width: 719px) {
  .sn-editbar {
    padding: 2px 3px;
    gap: 0;
    border-radius: var(--sn-radius);
    box-shadow: 0 4px 12px rgba(28, 28, 28, 0.22);
  }
  .sn-eb-btn {
    position: relative;
    width: 32px;
    height: 32px;
    padding: 7px;
  }
  .sn-eb-btn::after {
    content: "";
    position: absolute;
    inset: -6px; /* 32 + 12 = 44 px hit */
  }
  .sn-eb-format {
    order: 0;
    flex-basis: auto;
    justify-content: center;
    border: 0;
    padding: 0;
    margin: 0;
  }
  .sn-eb-dot { width: 12px; height: 12px; }
  .sn-editbar.is-docked {
    left: 8px;
    right: 8px;
    width: auto;
    max-width: none;
    justify-content: space-around;
    border-radius: var(--sn-radius);
  }
  .sn-compose {
    left: 8px;
    right: 8px;
    width: auto;
  }
  /* One useful row above the docked bar — never a 32 px-wide column
     that placePopover would measure as too tall and flip below the keys. */
  .sn-eb-palette {
    flex-wrap: nowrap;
    width: max-content;
    max-width: calc(100vw - 24px);
  }
}

@media (max-width: 719px) {
  html.sn-editing .sn-guestbar { display: none; }
}

/* ---------------------------------------------------------------- installed app */

/* Added to <html> when the page is running from the home screen (matchMedia on
   Android/desktop, navigator.standalone on iOS). There is no browser chrome to
   sit under, so the site nav compacts to a strip and the board takes the screen
   it just got back. Safe-area insets matter here — black-translucent means the
   status bar and the home indicator overlap the page. */
.sn-standalone {
  --nav-h: calc(2.75rem + env(safe-area-inset-top, 0px));
}
.sn-standalone .sn-nav {
  background: var(--cream);
  backdrop-filter: none;
  border-bottom: 0;
  padding: 0 10px;
  padding-top: env(safe-area-inset-top, 0px);
}
.sn-standalone .sn-nav-logo span,
.sn-standalone .sn-nav-section span { display: none; }
.sn-standalone .sn-nav-install { display: none !important; }
.sn-standalone .sn-nav-links { font-size: 0.62rem; }
.sn-standalone .sn-app {
  padding-bottom: calc(8px + env(safe-area-inset-bottom, 0px));
}
.sn-standalone .sn-selbar {
  bottom: calc(8px + env(safe-area-inset-bottom, 0px));
}
.sn-standalone .sn-guestbar { display: none; }

@media (prefers-reduced-motion: reduce) {
  .sn-card.is-filing,
  .sn-toast { transition: none; }
  .sn-card.is-pulsing,
  .sn-tab-count.is-bumped,
  .sn-side-count.is-bumped { animation: none; }
}
