/* MovieBrain: the library as one frameless grid, on the editor's paper. Every card is
   drawn at its final size from the index, filled with its picture's colour, and the
   picture fades in when it arrives. An opened item reads as a page in the editor's two
   voices. Tokens only (public/design-system/README.md). */

:root {
  --mb-page-x: var(--space-md);
  /* The choosing box: the design system's sketched box, drawn heavier, light and graphite */
  --mb-check-light: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Cpath d='M1.2 2.6C6 2.1 11 2.3 16.6 1.9M15.7 1.2C16.1 6 15.9 11 16.3 16.6M16.8 15.6C11.6 16.1 6.6 15.8 1.4 16.2M2.4 16.8C2.1 11.6 2.3 6.6 1.9 1.3' fill='none' stroke='oklch(0.985 0.006 85)' stroke-width='1.7' stroke-linecap='round'/%3E%3C/svg%3E");
  --mb-check-ink: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 18 18'%3E%3Cpath d='M1.2 2.6C6 2.1 11 2.3 16.6 1.9M15.7 1.2C16.1 6 15.9 11 16.3 16.6M16.8 15.6C11.6 16.1 6.6 15.8 1.4 16.2M2.4 16.8C2.1 11.6 2.3 6.6 1.9 1.3' fill='none' stroke='oklch(0.36 0.012 65)' stroke-width='1.7' stroke-linecap='round'/%3E%3C/svg%3E");
  /* The tallest an opened picture is drawn */
  --mb-view-h: calc(100vh - var(--space-lg) * 2);
  /* The page's width where it has a column of its own (under the picture on a narrow
     screen, under a video): about 70 characters to a line */
  --mb-measure: 34rem;
  /* The page's writing sizes, from the type scale and the chosen writing face */
  /* One face for all of MovieBrain, Schibsted Grotesk, in three sizes: a title, the
     words you read, and the small print about them. Two colours (ink, and muted for
     the small print), one weight beyond regular (the title's). MovieBrain is a library,
     not a writing tool, so the editor's second voice, a writing face for what was
     written, doesn't apply here (Mustafa, 2026-10-05). */
  --font-ui: "Google Sans Flex", "Schibsted Grotesk", system-ui, -apple-system, sans-serif;
  --font-text: var(--font-ui);
  --mb-title: 1.375rem;   /* 22 */
  --mb-body: 1rem;        /* 16 */
  --mb-small: 0.8125rem;  /* 13 */
}
[hidden] {
  display: none !important;
}
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
}
/* No scroll bars, anywhere: the page, an opened item, the search, the menus */
* {
  scrollbar-width: none;
}
*::-webkit-scrollbar {
  display: none;
}
body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg-canvas);
  color: var(--fg-default);
  font: 400 var(--text-ui) / 1.5 var(--font-ui);
  -webkit-font-smoothing: antialiased;
}
/* The editor's paper */
body::before,
.mb-view::before {
  content: "";
  position: fixed;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background: var(--paper-texture) 0 0 / var(--paper-texture-size) repeat;
  filter: var(--paper-texture-filter);
  mix-blend-mode: var(--paper-texture-blend);
  opacity: var(--paper-texture-opacity);
}
button,
textarea,
input {
  font: inherit;
  color: inherit;
}
/* Messages show over an opened item too */
.ds-status {
  z-index: var(--z-dialog);
}

/* ── The bar: search, kinds, size ─────────────────────────────────────────── */
.mb-bar {
  position: sticky;
  top: 0;
  z-index: 20;
  display: flex;
  align-items: flex-start;
  gap: var(--space-lg);
  padding: var(--space-xs) var(--mb-page-x);
  background: var(--bg-canvas);
  transition: box-shadow var(--dur-fast) var(--ease-out);
}
.mb-bar.is-scrolled {
  box-shadow: 0 1px 0 var(--border-subtle);
}
/* A fixed slot: a long question grows the field over the grid, never pushing it; and
   over the kinds, where the search has a row of its own (the kinds' words are
   positioned, for the pencil's underline, and would show through) */
.mb-search {
  position: relative;
  z-index: 1;
  flex: 1 1 auto;
  max-width: 680px;
  height: 38px;
}
.mb-search-box {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: flex-start;
  gap: var(--space-xs);
  min-height: 38px;
  box-sizing: border-box;
  padding: 0 var(--space-2xs) 0 var(--space-sm);
  background: var(--bg-surface);
  border: 1px solid var(--border-default);
  /* The design system's field (.ds-field), its bevel drawn large enough to read on a
     field this wide */
  border-radius: var(--radius-lg);
  corner-shape: var(--corner-shape);
  cursor: text;
  transition: border-color var(--dur-fast) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
.mb-search-box:hover {
  border-color: var(--border-strong);
}
.mb-search-box.is-tall {
  box-shadow: var(--shadow-overlay);
}
.mb-search-icon {
  flex: none;
  margin-top: 10px;
  color: var(--fg-subtle);
  transition: color var(--dur-base) var(--ease-out);
}
/* Search by meaning is the AI at work: the accent, while it looks */
.mb-search-box.is-searching .mb-search-icon {
  color: var(--accent);
}
.mb-search-box textarea {
  flex: 1 1 auto;
  min-width: 0;
  height: 22px;
  max-height: calc(22px * 4);
  margin: 6px 0;
  padding: 0;
  border: 0;
  outline: 0;
  resize: none;
  overflow-y: hidden;
  background: transparent;
  font-size: var(--text-ui-lg);
  line-height: 22px;
  color: var(--fg-default);
}
.mb-search-box textarea::placeholder {
  color: var(--fg-subtle);
}
/* Everything in the field sits on one line through the middle of its first row, 18px
   below the border: the icons by their middles, the picture by its middle, and the
   words and the count by the middle of their lowercase letters (Google Sans Flex's
   x-height, measured), which is where the eye reads a line of text. Its line boxes sit
   a pixel higher. On a taller field, everything stays on the first row. */
.mb-search-box .ds-icon-btn {
  flex: none;
  margin-top: 5px;
}
/* The picture searched with, in small print at the field's start. Clicked, it goes
   (with Undo); under the pointer it fades and the pencil strikes it, as it does a tag */
.mb-search-picture {
  position: relative;
  flex: none;
  width: 28px;
  height: 28px;
  margin-top: 4px;
  padding: 0;
  overflow: hidden;
  background: var(--bg-sunken);
  border: 1px solid var(--border-default);
  border-radius: var(--radius-xs);
  corner-shape: var(--corner-shape);
  cursor: pointer;
}
.mb-search-picture img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.mb-search-picture::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--mark-strike-image) center / 100% 6px no-repeat;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out);
  pointer-events: none;
}
.mb-search-picture:is(:hover, :focus-visible) img {
  opacity: 0.4;
}
.mb-search-picture:is(:hover, :focus-visible)::after {
  opacity: 1;
}
/* At its end, what the search is doing: the pencil's loops while it looks, then what
   it found, in small print, on the first line's centre */
.mb-search-state {
  flex: none;
  display: flex;
  align-items: center;
  height: 22px;
  margin: 6px 0;
  font: 400 var(--mb-small) / 1 var(--font-ui);
  color: var(--fg-muted);
  white-space: nowrap;
}
.mb-kinds,
.mb-choosing {
  display: flex;
  align-items: center;
  gap: var(--space-md);
  height: 38px;
}
.mb-kinds {
  overflow-x: auto;
}
/* Kinds are words in graphite; the one you're in is in ink, double-underlined by the
   red pencil (design system, "The section you're in") */
.mb-kinds button {
  position: relative;
  flex: none;
  padding: var(--space-3xs) 0;
  border: 0;
  background: none;
  font-size: var(--text-ui);
  color: var(--fg-subtle);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-out);
}
.mb-kinds button:hover,
.mb-kinds button[aria-pressed="true"] {
  color: var(--fg-default);
}
/* Without the pencil, a plain double underline */
.mb-kinds:not([data-pencil]) button[aria-pressed="true"] {
  text-decoration: underline double var(--accent);
  text-underline-offset: 6px;
}
.mb-kind-count {
  margin-left: 1px;
  font-size: var(--text-meta);
  color: var(--fg-subtle);
  font-variant-numeric: tabular-nums;
}
.mb-kind-count:empty {
  display: none;
}
/* While anything is chosen, its actions take the kinds' place (design system,
   "Choosing items in a grid"): how many, circled, and what can be done with them */
.mb-chosen-count {
  position: relative;
  padding: var(--space-3xs) var(--space-2xs);
  font-size: var(--text-ui);
  color: var(--fg-default);
  font-variant-numeric: tabular-nums;
}
.mb-choosing .ds-icon-btn + .ds-icon-btn {
  margin-left: calc(var(--space-md) * -1 + var(--space-3xs));
}
.mb-tools {
  display: flex;
  gap: var(--space-3xs);
  margin-left: auto;
  padding-top: 2px;
}
.mb-tools .ds-icon-btn[aria-pressed="true"],
.mb-tools .ds-icon-btn[aria-expanded="true"] {
  background: var(--bg-active);
  color: var(--fg-default);
}
/* The cleanup list has no grid to choose in or size */
.mb-bar.is-gone :is(#mb-choose, #mb-smaller, #mb-larger) {
  display: none;
}
/* Adding: the menu under its button */
.mb-add-menu {
  position: fixed;
  z-index: var(--z-popover);
  min-width: 180px;
}

/* ── Fresh from the server ──────────────────────────────────────────────────
   Both hang under the bar, so on a phone they ride with it as it tucks away, and
   float as the design system's floating controls do: the surface, a fine rule, the
   overlay shadow and cut corners. */
.mb-new,
.mb-pull {
  position: absolute;
  top: 100%;
  left: 50%;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  corner-shape: var(--corner-shape);
  background: var(--bg-surface);
  box-shadow: var(--shadow-overlay);
  color: var(--fg-default);
}
/* New items above, while you were further down */
.mb-new {
  display: inline-flex;
  align-items: center;
  gap: var(--space-3xs);
  height: 30px;
  margin-top: var(--space-xs);
  padding: 0 var(--space-sm) 0 var(--space-xs);
  translate: -50% 0;
  font: 500 var(--text-ui)/1 var(--font-ui);
  cursor: pointer;
  animation: mb-new-in var(--dur-slow) var(--ease-out);
}
.mb-new[hidden] {
  display: none;
}
.mb-new:hover {
  background: var(--bg-hover);
}
@keyframes mb-new-in {
  from { opacity: 0; translate: -50% -8px; }
}
/* The disc a pull at the top brings down (in the app on a phone's home screen): it
   follows the finger, its arrow turning, and takes the accent past the mark */
.mb-pull {
  display: none;
  place-items: center;
  width: 38px;
  height: 38px;
  color: var(--fg-muted);
  opacity: min(1, calc(var(--pull, 0) / 40));
  transform: translate(-50%, calc(var(--pull, 0) * 1px - 46px)) scale(min(1, calc(0.6 + var(--pull, 0) / 160)));
  transition: transform var(--dur-slow) var(--ease-out), opacity var(--dur-base) var(--ease-out), color var(--dur-fast) var(--ease-out);
  pointer-events: none;
}
.is-standalone .mb-pull {
  display: grid;
}
.mb-pull.is-pulling {
  transition: color var(--dur-fast) var(--ease-out);
}
.mb-pull.is-armed {
  color: var(--accent);
}
.mb-pull .ds-icon {
  width: 18px;
  height: 18px;
}

/* ── The grid ─────────────────────────────────────────────────────────────── */
.mb-grid {
  position: relative;
  margin: var(--space-2xs) var(--mb-page-x) var(--space-3xl);
  /* The grid keeps the card at the screen's top in place itself (relayout); the
     browser's own scroll anchoring would fight it as cards glide */
  overflow-anchor: none;
}
.mb-card {
  position: absolute;
  top: 0;
  left: 0;
  display: block;
  overflow: hidden;
  background: var(--bg-sunken);
  border-radius: var(--radius-xs);
  corner-shape: var(--corner-shape);
  contain: strict;
  color: inherit;
  text-decoration: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
.mb-card img,
.mb-card video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: top center;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
  user-select: none;
  -webkit-user-drag: none;
}
.mb-card.is-loaded img,
.mb-card video.is-playing {
  opacity: 1;
}
/* A picture already in memory shows at once, without fading */
.mb-card.is-instant img {
  transition: none;
}
/* Cards beneath an embed that has just found its height slide to their places */
.mb-card.is-reflowing {
  transition: transform var(--dur-reflow) var(--ease-reflow), height var(--dur-reflow) var(--ease-reflow);
}
.mb-label {
  position: absolute;
  left: var(--space-xs);
  bottom: var(--space-xs);
  max-width: calc(100% - var(--space-md));
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: var(--space-3xs) var(--space-2xs) 3px;
  /* A small caption in ink (Mustafa preferred it to a paper slip: lighter, less boxy) */
  background: var(--bg-inverse);
  color: var(--fg-inverse);
  opacity: 0;
  transform: translateY(2px);
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
  pointer-events: none;
  z-index: 2;
}
.mb-label-title {
  font-size: var(--text-meta);
  line-height: 1.35;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  overflow: hidden;
}
.mb-label-source {
  font-size: var(--text-micro);
  line-height: 1.3;
  opacity: 0.72;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mb-label-title:empty,
.mb-label-source:empty,
.mb-label:has(.mb-label-title:empty):has(.mb-label-source:empty) {
  display: none;
}
/* Under a pointer; not on a touch screen, where a tap leaves hover behind */
@media (hover: hover) {
  :root:not(.is-touch) .mb-card:hover .mb-label {
    opacity: 1;
    transform: none;
  }
}
.mb-card:focus-visible .mb-label {
  opacity: 1;
  transform: none;
}
/* A video's label leaves its speaker the corner */
.mb-card.has-video .mb-label {
  max-width: calc(100% - var(--space-md) - 30px);
}
/* Too small a card has no room for it. Choosing keeps it: it says what a picture is
   before it's chosen (Mustafa, 2026-10-17) */
.mb-card.is-small .mb-label {
  display: none;
}

/* A carousel's card swipes sideways through its slides (moviebrain.js, "Carousels in
   the grid"): its dots at its foot, as the opened view's, smaller; on the desk, arrows at
   its sides under the pointer, where the dots step aside for its label. The slide beside
   comes in on the card's own colour. */
.is-touch .mb-card.is-carousel {
  touch-action: pan-y;
}
.mb-slide-dots,
.mb-slide-step {
  display: none;
}
.mb-card.is-carousel .mb-slide-dots {
  position: absolute;
  left: 50%;
  bottom: var(--space-xs);
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 4px;
  transform: translateX(-50%);
  filter: drop-shadow(0 0 0.5px oklch(0.18 0.01 65 / 0.8)) drop-shadow(0 1px 2px oklch(0.18 0.01 65 / 0.45));
  pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.mb-card.is-carousel .mb-photo-dot {
  width: 5px;
  height: 5px;
}
:root:not(.is-touch) .mb-card.is-carousel .mb-slide-step {
  position: absolute;
  top: 50%;
  z-index: 3;
  display: grid;
  place-items: center;
  width: 28px;
  height: 28px;
  margin-top: -14px;
  color: oklch(0.985 0.006 85);
  filter: drop-shadow(0 0 0.5px oklch(0.18 0.01 65 / 0.9)) drop-shadow(0 1px 2px oklch(0.18 0.01 65 / 0.45));
  opacity: 0;
  cursor: pointer;
  transition: opacity var(--dur-fast) var(--ease-out);
}
.mb-slide-step.is-back {
  left: var(--space-3xs);
}
.mb-slide-step.is-ahead {
  right: var(--space-3xs);
}
@media (hover: hover) {
  :root:not(.is-touch) .mb-card.is-carousel.can-back:hover .mb-slide-step.is-back,
  :root:not(.is-touch) .mb-card.is-carousel.can-ahead:hover .mb-slide-step.is-ahead {
    opacity: 1;
  }
  :root:not(.is-touch) .mb-card.is-carousel:hover .mb-slide-dots {
    opacity: 0;
  }
}
.mb-slide-ghost {
  position: absolute;
  inset: 0;
  z-index: 2;
  background: inherit;
}
.mb-card .mb-slide-ghost img {
  opacity: 1;
  transition: none;
}
.mb-card.is-sliding :is(img, video, .mb-fallback, .mb-slide-ghost) {
  transition: none;
}
.mb-card.is-settling :is(img, video, .mb-fallback, .mb-slide-ghost) {
  transition: transform 260ms cubic-bezier(0.22, 1, 0.36, 1);
}

/* Choosing: a sketched check box at every card's top right, ticked by the pencil,
   and the pencil's box round each chosen card */
.mb-check,
.mb-chosen-frame {
  position: absolute;
  z-index: 3;
  pointer-events: none;
}
.mb-check {
  top: 5px;
  right: 5px;
  width: 18px;
  height: 18px;
  background: var(--mb-check-light) center / 100% no-repeat;
  /* A close dark edge, doubled, then a soft shadow: the light strokes hold on white too */
  filter: drop-shadow(0 0 0.5px oklch(0.18 0.01 65 / 0.9)) drop-shadow(0 0 0.5px oklch(0.18 0.01 65 / 0.9)) drop-shadow(0 1px 2px oklch(0.18 0.01 65 / 0.35));
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out);
}
/* On paper, graphite needs no halo */
.mb-card.is-words .mb-check {
  background-image: var(--mb-check-ink);
  filter: none;
}
[data-theme="dark"] .mb-card.is-words .mb-check {
  background-image: var(--mb-check-light);
}
/* While choosing, a cover's source leaves the box its corner */
.mb-grid.is-choosing .mb-cover-from {
  right: 2.6em;
}
.mb-chosen-frame {
  inset: 4px;
}
.mb-grid.is-choosing .mb-check {
  opacity: 1;
  pointer-events: auto;
  cursor: pointer;
}
/* Under the pointer, a card offers its check box: a click there starts choosing */
@media (hover: hover) and (pointer: fine) {
  :root:not(.is-touch) .mb-grid .mb-card:hover .mb-check {
    opacity: 1;
    pointer-events: auto;
    cursor: pointer;
  }
}
/* While choosing, Instagram's player doesn't take the click */
.mb-grid.is-choosing .mb-embed-host {
  pointer-events: none;
}
/* The titles of what's about to go, each struck through in the confirmation */
.mb-confirm {
  padding: 0;
}
.mb-confirm::backdrop {
  background: var(--scrim);
}
.mb-confirm-subjects {
  display: grid;
  gap: var(--space-2xs);
  justify-items: start;
  min-width: 0;
}
/* One line each, so the pencil's strike runs the length of it */
.mb-confirm-subjects .ds-alert-subject {
  max-width: 100%;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Cards of words: a clipping on paper, in the writing face ──────────────── */
.mb-card.is-words,
.mb-card.is-cover,
.mb-fallback {
  background: var(--bg-surface);
  box-shadow: inset 0 0 0 1px var(--border-subtle);
}
.mb-words {
  position: absolute;
  margin: 0;
  font-family: var(--font-ui);
  color: var(--text-ink);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: break-word;
}
/* The post a post quotes, in a box beneath its words */
.mb-quoted {
  position: absolute;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  box-shadow: inset 0 0 0 1px var(--border-default);
  border-radius: var(--radius-xs);
  corner-shape: var(--corner-shape);
}
.mb-quoted-by {
  display: block;
  font-family: var(--font-ui);
  color: var(--fg-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mb-quoted-words {
  font-family: var(--font-ui);
  color: var(--text-ink);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  overflow: hidden;
  overflow-wrap: break-word;
}
.mb-by {
  position: absolute;
  font-size: var(--text-meta);
  line-height: 1.2;
  color: var(--fg-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ── Covers: anything without a picture gets a riso doodle (doodles.js), its title
   in the writing face, and where it's from. Sizes are in ems of the card's size. ── */
.mb-cover-from {
  position: absolute;
  top: 1em;
  left: 1.15em;
  right: 1.15em;
  font-family: var(--font-ui);
  font-size: 0.78em;
  line-height: 1.3;
  color: var(--fg-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  z-index: 1;
}
.mb-cover-art {
  position: absolute;
  left: 50%;
  top: 44%;
  width: 52%;
  height: 50%;
  display: grid;
  place-items: center;
  transform: translate(-50%, -50%);
  pointer-events: none;
}
.mb-cover-art .ds-doodle {
  width: 100%;
  height: 100%;
}
.mb-cover-title {
  position: absolute;
  left: 1.15em;
  right: 1.15em;
  bottom: 1em;
  margin: 0;
  font-family: var(--font-ui);
  font-size: 1.32em;
  line-height: 1.16;
  letter-spacing: -0.005em;
  color: var(--text-ink);
  overflow-wrap: break-word;
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  z-index: 1;
}
/* A picture that couldn't be had: its cover, in the same place and size */
.mb-fallback {
  position: absolute;
  inset: 0;
  display: none;
}
.mb-card.is-fallback .mb-fallback {
  display: block;
}
.mb-card.is-fallback img {
  display: none;
}

/* ── A reel not yet collected: its cover, then Instagram's own player over it ── */
.mb-card.is-embed {
  cursor: default;
}
.mb-embed-host {
  position: absolute;
  inset: 0;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
}
.mb-card.is-embedded .mb-embed-host {
  opacity: 1;
}
/* Once the player is drawn, the cover goes: the player has clear parts */
.mb-card.is-embedded > .mb-cover-from,
.mb-card.is-embedded > .mb-cover-art,
.mb-card.is-embedded > .mb-cover-title {
  visibility: hidden;
}
.mb-embed-host iframe,
.mb-view-embed iframe {
  position: absolute;
  top: 0;
  left: 0;
  border: 0;
  transform-origin: top left;
  background: transparent;
}
.mb-view-embed {
  position: relative;
  overflow: hidden;
}
.mb-empty {
  margin: var(--space-2xl) var(--mb-page-x);
  color: var(--fg-muted);
}

/* ── Boards: chosen items, shared ─────────────────────────────────────────────
   A board, open, has its head over its items in the grid: the title (renamed by a
   click, as an item's is) and the brief, on a ruled line the pencil draws in while you
   write; Share and Delete beside them. Boards lists them as contact sheets: each
   board's first pictures, its title and how many. */
.mb-board {
  display: flex;
  align-items: flex-start;
  gap: var(--space-md);
  margin: var(--space-md) var(--mb-page-x) var(--space-sm);
}
.mb-board-words {
  display: grid;
  gap: var(--space-2xs);
  flex: 1 1 auto;
  min-width: 0;
  max-width: var(--mb-measure);
}
.mb-board-title {
  margin: 0;
  font: 600 var(--mb-title) / 1.25 var(--font-ui);
  letter-spacing: -0.012em;
  color: var(--text-ink);
  overflow-wrap: anywhere;
}
.mb-board-title-row {
  position: relative;
}
.mb-board-title.is-editable {
  cursor: text;
  outline: none;
}
.mb-board-title.is-editable:empty::before {
  content: attr(data-placeholder);
  color: var(--text-ink-placeholder);
}
.mb-board-meta {
  display: block;
  margin: 0;
  font: 400 var(--mb-small) / 1.45 var(--font-ui);
  color: var(--fg-muted);
  font-variant-numeric: tabular-nums;
}
.mb-board-tools {
  flex: none;
  display: flex;
  align-items: center;
  gap: var(--space-3xs);
  margin-left: auto;
}
/* Where a new board's link was asked to go, waiting until it's named */
.mb-board-send {
  margin-right: var(--space-2xs);
}
.mb-board-send .ds-icon {
  width: 14px;
  height: 14px;
}
:is(.mb-board-tools, .mb-view-tools, .mb-choosing, .mb-peek-tools) .ds-icon-btn[aria-expanded="true"] {
  background: var(--bg-active);
  color: var(--fg-default);
}
/* The list of boards has no grid to choose in or size */
.mb-bar.is-boards :is(#mb-choose, #mb-smaller, #mb-larger) {
  display: none;
}
.mb-boards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: var(--space-xl) var(--space-md);
  margin: var(--space-md) var(--mb-page-x) var(--space-3xl);
}
.mb-boards > .mb-gone-none {
  grid-column: 1 / -1;
}
.mb-board-tile {
  display: grid;
  align-content: start;
  gap: var(--space-3xs);
  min-width: 0;
  padding: 0;
  border: 0;
  background: none;
  color: inherit;
  text-align: left;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}
/* Its first four pictures, on the paper: one fills it; two side by side; three, one
   large and two stacked; four in a square */
.mb-board-cover {
  display: grid;
  gap: 2px;
  aspect-ratio: 4 / 3;
  max-width: 100%;
  margin-bottom: var(--space-2xs);
  overflow: hidden;
  border-radius: var(--radius-xs);
  corner-shape: var(--corner-shape);
  background: var(--bg-canvas);
}
.mb-board-cover[data-count="0"] {
  background: var(--bg-sunken);
}
.mb-board-cover img {
  display: block;
  width: 100%;
  height: 100%;
  min-width: 0;
  min-height: 0;
  object-fit: cover;
  background: var(--bg-sunken);
  transition: filter var(--dur-fast) var(--ease-out);
}
.mb-board-cover[data-count="2"] {
  grid-template-columns: 1fr 1fr;
}
.mb-board-cover[data-count="3"] {
  grid-template-columns: 3fr 2fr;
  grid-template-rows: 1fr 1fr;
}
.mb-board-cover[data-count="3"] img:first-child {
  grid-row: span 2;
}
.mb-board-cover[data-count="4"] {
  grid-template-columns: 1fr 1fr;
  grid-template-rows: 1fr 1fr;
}
.mb-board-tile:is(:hover, :focus-visible) .mb-board-cover img {
  filter: brightness(0.93);
}
.mb-board-name {
  overflow: hidden;
  font: 600 var(--mb-body) / 1.3 var(--font-ui);
  color: var(--text-ink);
  white-space: nowrap;
  text-overflow: ellipsis;
}
.mb-board-name.is-untitled {
  font-weight: 400;
  color: var(--fg-muted);
}
/* Where a link goes, and which board items join: under their button */
.mb-pop-menu {
  position: fixed;
  z-index: calc(var(--z-popover) + 1);
  min-width: 180px;
  max-width: min(320px, calc(100vw - 16px));
  max-height: min(420px, calc(100vh - 96px));
  overflow-y: auto;
}
.mb-pop-menu .ds-menu-item {
  display: block;
  line-height: 30px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
.is-touch .mb-pop-menu .ds-menu-item {
  height: 44px;
  line-height: 44px;
  font-size: var(--mb-body);
}
/* A board's note on an item, on its shared page: the line it was written on */
.mb-board-note {
  margin: 0 0 var(--space-2xl);
  padding: var(--space-2xs) 0;
  border-bottom: 1px solid var(--border-subtle);
  font: 400 var(--mb-body) / 1.5 var(--font-ui);
  color: var(--text-ink);
  white-space: pre-line;
  overflow-wrap: anywhere;
}
/* A shared board's page: no search and no kinds (the library isn't there to look
   through), only the board. The bear, the site's mark, sits beside the title at the
   title's height, and the brief runs under both from the grid's left edge (Mustafa,
   2026-10-17): beside a long brief, the bear looked small and left a column of white
   under it. */
:root[data-board] :is(.mb-bar, .mb-find) {
  display: none;
}
:root[data-board] .mb-board {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: start;
  gap: var(--space-2xs) var(--space-xs);
  margin: var(--space-xl) var(--mb-page-x) var(--space-lg);
}
:root[data-board] .mb-board-words {
  display: contents;
}
:root[data-board] .mb-board-title {
  grid-column: 2;
  grid-row: 1;
}
:root[data-board] p.mb-board-brief {
  grid-column: 1 / -1;
  grid-row: 2;
  max-width: var(--mb-measure);
}
/* Centred on the title's first line (a bear 31px tall, a line 27.5px) */
.mb-board-mark {
  grid-column: 1;
  grid-row: 1;
  display: block;
  width: 30px;
  margin-top: -2px;
  -webkit-tap-highlight-color: transparent;
}
.mb-board-mark img {
  display: block;
  width: 100%;
  height: auto;
}
p.mb-board-brief {
  margin: 0;
  font: 400 var(--mb-body) / 1.55 var(--font-ui);
  color: var(--text-ink);
  white-space: pre-line;
  overflow-wrap: anywhere;
}
@media (max-width: 600px) {
  .mb-boards {
    grid-template-columns: 1fr 1fr;
    gap: var(--space-lg) var(--space-sm);
  }
  :root[data-board] .mb-board {
    margin-top: var(--space-lg);
  }
}

/* ── Gone from their sources: the cleanup list ───────────────────────────────
   A column on the paper. Each dead link's title is struck through in graphite, as
   the editor strikes what's gone; a chosen row's box is ticked by the pencil. */
.mb-gone {
  max-width: 720px;
  margin: var(--space-md) auto var(--space-3xl);
  padding: 0 var(--mb-page-x);
}
.mb-gone-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  min-height: var(--control-h);
  margin-bottom: var(--space-xl);
}
.mb-gone-state {
  margin: 0;
  font-size: var(--text-ui);
  color: var(--fg-muted);
}
.mb-gone-actions {
  display: flex;
  gap: var(--space-xs);
}
.mb-gone-group + .mb-gone-group {
  margin-top: var(--space-2xl);
}
.mb-gone-label {
  display: flex;
  gap: var(--space-2xs);
  margin: 0 0 var(--space-xs);
  font: 500 var(--text-meta) / 1.3 var(--font-ui);
  color: var(--fg-subtle);
}
.mb-gone-n {
  font-variant-numeric: tabular-nums;
}
.mb-gone-list {
  display: grid;
}
.mb-gone-row {
  display: flex;
  align-items: flex-start;
  gap: var(--space-sm);
  padding: var(--space-2xs) 0;
  cursor: pointer;
}
.mb-gone-box {
  position: relative;
  flex: none;
  width: 18px;
  height: 18px;
  margin-top: 3px;
  padding: 0;
  border: 0;
  background: var(--mark-check-box-image) center / 18px 18px no-repeat;
  cursor: pointer;
}
/* The original, to see for yourself */
.mb-gone-open {
  flex: none;
  margin-left: auto;
  color: var(--fg-subtle);
}
.mb-gone-open:hover,
.mb-gone-open:focus-visible {
  color: var(--fg-default);
}
/* One line: the struck title, then where it was from */
.mb-gone-what {
  display: flex;
  align-items: baseline;
  gap: var(--space-xs);
  min-width: 0;
}
.mb-gone-title {
  flex: 0 1 auto;
  min-width: 0;
  font: 400 var(--mb-body) / 1.45 var(--font-ui);
  color: var(--text-ink);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  background: var(--mark-strike-image) left 58% / 100% 6px no-repeat;
  transition: color var(--dur-fast) var(--ease-out);
}
.mb-gone-row:not(.is-chosen) .mb-gone-title {
  color: var(--fg-muted);
}
.mb-gone-meta {
  flex: none;
  font-size: var(--text-meta);
  color: var(--fg-subtle);
}
.mb-gone-meta:empty {
  display: none;
}
/* Nothing gone: a doodle, and one line */
.mb-gone-none {
  display: grid;
  justify-items: center;
  gap: var(--space-sm);
  padding: var(--space-3xl) 0;
  color: var(--fg-muted);
}
.mb-gone-none p {
  margin: 0;
}
.mb-gone-none-art {
  display: grid;
  place-items: center;
  width: 128px;
  height: 128px;
}
.mb-gone-none-art .ds-doodle {
  width: 100%;
  height: 100%;
}

/* ── Adding: files dropped on the page, and a note of your own ─────────────── */
.mb-drop {
  position: fixed;
  inset: 0;
  z-index: var(--z-dialog);
  display: grid;
  place-items: center;
  padding: var(--space-lg);
  pointer-events: none;
  background: color-mix(in oklch, var(--bg-canvas) 90%, transparent);
}
.mb-drop-sheet {
  position: relative;
  display: grid;
  place-items: center;
  width: 100%;
  height: 100%;
  color: var(--fg-default);
  font: 500 var(--text-title) / 1.2 var(--font-ui);
}
.mb-drop-sheet p {
  margin: 0;
}
.mb-drop-sheet > .pencil path {
  stroke-width: 2;
}
.mb-compose {
  width: min(560px, calc(100vw - 32px));
  padding: 0;
}
.mb-compose::backdrop {
  background: var(--scrim);
}
/* The writer's own words, in the writing face, on the dialog's paper */
.mb-compose-form {
  display: grid;
  gap: var(--space-sm);
  padding: var(--space-lg) var(--space-lg) var(--space-md);
}
.mb-compose-title,
.mb-compose-text {
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  outline: none;
  color: var(--text-ink);
  font-family: var(--font-ui);
}
.mb-compose-title {
  font-size: var(--mb-title);
  font-weight: 600;
  line-height: 1.25;
}
.mb-compose-text {
  min-height: 180px;
  resize: vertical;
  font-size: var(--mb-body);
  line-height: 1.55;
}
.mb-compose-title::placeholder,
.mb-compose-text::placeholder {
  color: var(--text-ink-placeholder);
}

/* ── On a touch screen ─────────────────────────────────────────────────────────
   Phones and tablets (the page marks <html> .is-touch). Made for the thumb, not
   shrunk from the desk: one slim row at the top, the kinds and the choose button,
   and nothing else. The search is a raised glass button at the bottom right; a tap
   opens the keyboard in a field that appears at the top. The grid is Instagram's
   Explore: tiles whose videos play, silently; a tap opens one, and a long press brings
   it up close, with its sound. */
.mb-find,
.mb-sound {
  display: none;
}
video.mb-inline {
  z-index: 1;
}
/* A video's speaker, in the corner, with no tile behind it (as the check box): on the
   desk a control that shows under the pointer */
.mb-card.has-video .mb-sound {
  position: absolute;
  right: var(--space-2xs);
  bottom: var(--space-2xs);
  z-index: 3;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  color: oklch(0.985 0.006 85);
  filter: drop-shadow(0 0 0.5px oklch(0.18 0.01 65 / 0.9)) drop-shadow(0 1px 2px oklch(0.18 0.01 65 / 0.45));
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--dur-base) var(--ease-out);
}
:root:not(.is-touch) .mb-card.has-video .mb-sound {
  pointer-events: auto;
  cursor: pointer;
}
@media (hover: hover) {
  :root:not(.is-touch) .mb-card.has-video:hover .mb-sound {
    opacity: 1;
  }
}
/* With its sound on, the speaker stays */
.mb-card.has-video.is-sounding .mb-sound {
  opacity: 1;
}
/* While choosing, a click chooses: no speaker */
.mb-grid.is-choosing .mb-card .mb-sound {
  display: none;
}
.is-touch :is(#mb-refresh, #mb-add, #mb-smaller, #mb-larger) {
  display: none;
}
/* In the app on a phone's home screen the top doesn't stretch: a pull there refreshes */
:root.is-standalone,
.is-standalone body {
  overscroll-behavior-y: none;
}
.is-touch .mb-bar {
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-xs);
  padding: 0 var(--space-xs) 0 var(--mb-page-x);
  transition: transform var(--dur-base) var(--ease-out), box-shadow var(--dur-fast) var(--ease-out);
}
/* Scrolling down, the bar steps aside; scrolling up brings it back */
.is-touch .mb-bar.is-tucked {
  transform: translateY(-100%);
  box-shadow: none;
}
.is-touch .mb-search {
  display: none;
  flex-basis: 100%;
  max-width: none;
  order: -1;
  margin: var(--space-xs) var(--space-2xs) var(--space-3xs) 0;
}
.is-touch .mb-bar.is-finding .mb-search,
.is-touch .mb-bar:has(#mb-query:not(:placeholder-shown)) .mb-search,
.is-touch .mb-bar:has(.mb-search-box.has-picture) .mb-search {
  display: block;
}
.is-touch :is(.mb-kinds, .mb-choosing) {
  flex: 1 1 0%;
  min-width: 0;
  height: 46px;
}
/* The kinds run off the edge, fading, so it's plain they scroll */
.is-touch .mb-kinds {
  gap: var(--space-lg);
  padding-right: var(--space-lg);
  -webkit-mask-image: linear-gradient(90deg, black calc(100% - 32px), transparent);
  mask-image: linear-gradient(90deg, black calc(100% - 32px), transparent);
}
.is-touch .mb-kinds button {
  padding: var(--space-xs) 0;
}
.is-touch .mb-tools {
  padding-top: 0;
}
/* iOS zooms into any field under 16px when it's tapped, and stays zoomed, so the
   whole page then slides sideways: on a touch screen every field is 16px (and the
   tags with their field) */
.is-touch :is(#mb-query, .mb-tag-input, .mb-notes, .mb-tag) {
  font-size: 16px;
}
.is-touch .mb-compose-text {
  font-size: var(--mb-body);
}
/* No hover on glass: a tap leaves it behind on whatever was under the finger */
.is-touch .ds-icon-btn:hover:not(:active, [aria-pressed="true"]) {
  background: transparent;
}
/* The search button, in glass as Apple's newest controls are: nearly clear, the grid
   behind it softened and brightened, a rim that catches the light at the top left and
   glints again at the bottom right, and a sheen across its upper half */
.is-touch .mb-find {
  --glass-tint: oklch(0.99 0.004 85 / 0.16);
  --glass-light: oklch(0.99 0.004 85);
  --glass-shade: oklch(0.2 0.02 60);
  position: fixed;
  /* In the corner, level with Safari's address pill. iOS 26 Safari counts its floating
     toolbar in the bottom safe area, which sat the button far above the corner; the
     pill keeps to the middle, so the corner beside it is free. */
  right: max(var(--space-md), env(safe-area-inset-right));
  bottom: max(var(--space-md), calc(env(safe-area-inset-bottom) - 44px));
  z-index: 30;
  display: grid;
  place-items: center;
  width: 56px;
  height: 56px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  corner-shape: round;
  background: var(--glass-tint);
  -webkit-backdrop-filter: blur(5px) saturate(1.9) brightness(1.1);
  backdrop-filter: blur(5px) saturate(1.9) brightness(1.1);
  box-shadow:
    0 10px 28px color-mix(in oklch, var(--glass-shade) 20%, transparent),
    0 2px 6px color-mix(in oklch, var(--glass-shade) 12%, transparent),
    inset 0 1px 1px color-mix(in oklch, var(--glass-light) 80%, transparent),
    inset 0 -1px 1.5px color-mix(in oklch, var(--glass-light) 30%, transparent),
    inset 0 0 14px color-mix(in oklch, var(--glass-light) 22%, transparent);
  color: var(--fg-default);
  isolation: isolate;
  transition: opacity var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out), -webkit-backdrop-filter var(--dur-fast) var(--ease-out), backdrop-filter var(--dur-fast) var(--ease-out);
}
/* The rim: a hairline of light, brightest where the light falls */
.is-touch .mb-find::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: -1;
  padding: 1px;
  border-radius: inherit;
  background: linear-gradient(135deg,
    color-mix(in oklch, var(--glass-light) 95%, transparent) 0%,
    color-mix(in oklch, var(--glass-light) 18%, transparent) 38%,
    color-mix(in oklch, var(--glass-light) 0%, transparent) 55%,
    color-mix(in oklch, var(--glass-light) 55%, transparent) 100%);
  -webkit-mask: linear-gradient(black 0 0) content-box, linear-gradient(black 0 0);
  -webkit-mask-composite: xor;
  mask: linear-gradient(black 0 0) content-box exclude, linear-gradient(black 0 0);
  pointer-events: none;
}
/* The sheen: light lying across the dome */
.is-touch .mb-find::after {
  content: "";
  position: absolute;
  top: 3px;
  left: 9px;
  right: 9px;
  height: 46%;
  z-index: -1;
  border-radius: 50% 50% 45% 45% / 70% 70% 30% 30%;
  background: linear-gradient(to bottom, color-mix(in oklch, var(--glass-light) 42%, transparent), color-mix(in oklch, var(--glass-light) 0%, transparent));
  pointer-events: none;
}
:root[data-theme="dark"].is-touch .mb-find {
  --glass-tint: oklch(0.99 0.004 85 / 0.08);
  --glass-light: oklch(0.92 0.006 85);
  --glass-shade: oklch(0.05 0 0);
}
/* Pressed, the glass gives a little and brightens */
.is-touch .mb-find:active {
  transform: scale(0.92);
  -webkit-backdrop-filter: blur(5px) saturate(2.1) brightness(1.2);
  backdrop-filter: blur(5px) saturate(2.1) brightness(1.2);
}
.is-touch .mb-find .ds-icon {
  width: 23px;
  height: 23px;
  stroke-width: 2.1;
  filter: drop-shadow(0 0.5px 0.5px color-mix(in oklch, var(--glass-light) 70%, transparent));
}
/* A held card dims a little, and opens when held long enough; no callout */
.is-touch .mb-card {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  user-select: none;
  transition: filter var(--dur-base) var(--ease-out);
}
.is-touch .mb-card.is-pressing {
  filter: brightness(0.86);
}

/* The grid on a touch screen is Instagram's Explore (layout.js, tiles): edge to edge, a
   hairline between tiles cut square, each picture centred in its tile. Nothing is laid
   over a tile to say it's a video or a carousel: its picture shows it (Mustafa,
   2026-10-23). */
.is-touch .mb-grid {
  margin-left: env(safe-area-inset-left, 0px);
  margin-right: env(safe-area-inset-right, 0px);
}
.is-touch .mb-grid .mb-card {
  border-radius: 0;
}
.is-touch .mb-grid .mb-card :is(img, video) {
  object-position: center;
}
/* A tile whose card is up close is empty until it's back */
.mb-card.is-lifted {
  visibility: hidden;
}

/* ── Up close (moviebrain.js): a card held on a touch screen, over the grid, which
   blurs. It's whole on a sheet of paper; a link's or an article's name under it, in the
   page's sizes; its tools under that, as icons. The blur, the paper and the picture are
   apart, so each can move on its own as the card comes out of its tile and goes back
   into it. It lies under the opened item, which comes in over it. ── */
.mb-peek {
  position: fixed;
  inset: 0;
  z-index: calc(var(--z-popover) - 1);
  display: grid;
  place-items: center;
  padding: max(var(--space-md), env(safe-area-inset-top)) max(var(--space-md), env(safe-area-inset-right)) max(var(--space-md), env(safe-area-inset-bottom)) max(var(--space-md), env(safe-area-inset-left));
  touch-action: none;
  overscroll-behavior: contain;
  -webkit-user-select: none;
  user-select: none;
  -webkit-touch-callout: none;
  -webkit-tap-highlight-color: transparent;
}
.mb-peek.is-closing {
  pointer-events: none;
}
.mb-peek-backdrop {
  position: absolute;
  inset: 0;
  background: var(--scrim);
  -webkit-backdrop-filter: blur(12px);
  backdrop-filter: blur(12px);
}
/* Moved from its top left corner, so it can be laid exactly over a tile */
.mb-peek-sheet {
  position: relative;
  display: flex;
  flex-direction: column;
  max-width: 100%;
  transform-origin: 0 0;
}
.mb-peek-paper {
  position: absolute;
  inset: 0;
  background: var(--bg-surface);
  border-radius: var(--radius-sm);
  corner-shape: var(--corner-shape);
  box-shadow: var(--shadow-modal);
}
/* The picture, its top corners the paper's; on its way in and out it's cut as its tile
   cuts it */
.mb-peek-stage {
  position: relative;
  flex: none;
  align-self: center;
  clip-path: inset(0 round var(--radius-sm) var(--radius-sm) 0 0);
}
.mb-peek-caption,
.mb-peek-tools {
  position: relative;
}
.mb-peek .mb-card {
  border-radius: 0;
  touch-action: none;
}
.mb-peek .mb-card :is(img, video) {
  object-position: center;
}
/* Its name is under it, and its sound is what you hear */
.mb-peek .mb-card :is(.mb-label, .mb-sound) {
  display: none;
}
.mb-peek-caption {
  display: grid;
  gap: var(--space-3xs);
  padding: var(--space-sm) var(--space-md) 0;
}
.mb-peek-title {
  margin: 0;
  font: 400 var(--mb-body) / 1.35 var(--font-ui);
  color: var(--text-ink);
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 3;
  overflow: hidden;
  overflow-wrap: anywhere;
}
.mb-peek-source {
  margin: 0;
  font: 400 var(--mb-small) / 1.35 var(--font-ui);
  color: var(--fg-muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.mb-peek-caption :empty {
  display: none;
}
.mb-peek-tools {
  display: flex;
  align-items: center;
  padding: var(--space-2xs);
}
.mb-peek-tools .ds-icon-btn {
  width: 44px;
  height: 44px;
}
.mb-peek-gap {
  flex: 1;
}

/* ── One item, opened: the media on the paper, and a page beside it ─────────── */
.mb-view:focus {
  outline: none;
}
.mb-view {
  position: fixed;
  inset: 0;
  z-index: var(--z-popover);
  display: grid;
  grid-template-columns: minmax(0, 1fr) min(440px, 44vw);
  background: var(--bg-canvas);
  isolation: isolate;
  animation: mb-view-in var(--dur-base) var(--ease-out);
}
@keyframes mb-view-in {
  from { opacity: 0; }
}
.mb-view-media {
  position: relative;
  display: grid;
  place-items: center;
  min-width: 0;
  min-height: 0;
  padding: var(--space-lg);
  overflow: hidden;
}
.mb-view-media > img,
.mb-view-media > video,
.mb-view-media > .mb-view-frame,
.mb-view-media > .mb-view-embed {
  max-width: 100%;
  max-height: var(--mb-view-h);
  border-radius: var(--radius-xs);
  corner-shape: var(--corner-shape);
  box-shadow: var(--shadow-raised);
}
.mb-view-frame {
  position: relative;
  overflow: hidden;
  background: var(--bg-sunken);
}
.mb-view-frame > img,
.mb-view-frame > video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.mb-view-frame > .mb-view-full {
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.mb-view-frame > .mb-view-full.is-loaded {
  opacity: 1;
}
/* A carousel's dots: where you are, with no tile behind them, lit like the check box so
   they read on any photo without covering it */
.mb-photo-dots {
  position: absolute;
  left: 50%;
  bottom: var(--space-sm);
  z-index: 2;
  display: flex;
  align-items: center;
  gap: 5px;
  transform: translateX(-50%);
  filter: drop-shadow(0 0 0.5px oklch(0.18 0.01 65 / 0.8)) drop-shadow(0 1px 2px oklch(0.18 0.01 65 / 0.45));
  pointer-events: none;
}
.mb-photo-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  corner-shape: round;
  background: oklch(0.985 0.006 85 / 0.5);
  transition: background-color var(--dur-fast) var(--ease-out), transform var(--dur-fast) var(--ease-out);
}
.mb-photo-dot.is-current {
  background: oklch(0.985 0.006 85);
  transform: scale(1.2);
}
.mb-photo-dot.is-edge {
  transform: scale(0.6);
}
/* Over a video slide, above its player's controls */
.mb-view-media.is-playable .mb-photo-dots {
  bottom: calc(var(--space-sm) + 44px);
}
/* Swiped on a touch screen: sideways moves through, up and down is the page's scroll */
.is-touch .mb-view {
  touch-action: pan-y;
}
/* The media's sides, on the desk: wide zones its full height, each with a thin arrow
   that shows faintly while the pointer is over the media and fully over its own side.
   Over a photo, a cover or words they lie on top; a video or Instagram's player keeps
   its controls, so there they lie under it and take only the space beside it. */
.mb-travel {
  position: absolute;
  top: 0;
  bottom: 0;
  z-index: 1;
  display: grid;
  align-items: center;
  width: clamp(64px, 16%, 150px);
  padding: 0 var(--space-sm);
  border: 0;
  background: none;
  color: var(--fg-default);
  cursor: pointer;
}
.mb-travel.is-back {
  left: 0;
  justify-items: start;
}
.mb-travel.is-ahead {
  right: 0;
  justify-items: end;
}
.mb-travel[hidden],
.is-touch .mb-travel {
  display: none;
}
.mb-travel .ds-icon {
  width: 30px;
  height: 30px;
  stroke-width: 1.25;
  opacity: 0;
  filter: drop-shadow(0 0 1px var(--bg-canvas)) drop-shadow(0 0 6px var(--bg-canvas));
  transition: opacity var(--dur-fast) var(--ease-out), translate var(--dur-fast) var(--ease-out);
}
.mb-view-media:hover .mb-travel .ds-icon {
  opacity: 0.3;
}
.mb-view-media .mb-travel:is(:hover, :focus-visible) .ds-icon {
  opacity: 0.85;
}
.mb-travel.is-back:hover .ds-icon {
  translate: -2px 0;
}
.mb-travel.is-ahead:hover .ds-icon {
  translate: 2px 0;
}
.mb-view-media.is-playable > :not(.mb-travel) {
  position: relative;
  z-index: 2;
}
/* A post or note without a picture: its words, large, in the writing face */
/* A post or note without a picture: its words are the item, at the size everything
   is read at, centred while short; a long one scrolls in its column, never clipped */
.mb-view-media:has(> .mb-view-words) {
  display: flex;
  flex-direction: column;
  align-items: center;
  overflow-y: auto;
}
.mb-view-words {
  max-width: 34em;
  margin: auto 0;
  font: 400 var(--mb-body) / 1.55 var(--font-ui);
  color: var(--text-ink);
  white-space: pre-wrap;
  overflow-wrap: anywhere;
}
/* A note or an article, read where it opens (articleFrom in moviebrain.js): at the
   reading measure, scrolling in its column, in the face and sizes used everywhere */
.mb-view-media:has(> .mb-view-article) {
  display: block;
  overflow-y: auto;
}
.mb-view-article {
  max-width: var(--mb-measure);
  margin: 0 auto;
  padding: var(--space-lg) 0 var(--space-3xl);
  font: 400 var(--mb-body) / 1.6 var(--font-ui);
  color: var(--text-ink);
  overflow-wrap: break-word;
}
.mb-view-article > :first-child {
  margin-top: 0;
}
.mb-view-article :is(p, ul, ol, blockquote, pre) {
  margin: 0 0 1em;
}
.mb-view-article :is(h3, h4) {
  margin: 1.75em 0 0.5em;
  font-weight: 600;
  line-height: 1.3;
}
.mb-view-article h3 {
  font-size: var(--mb-title);
}
.mb-view-article h4 {
  font-size: var(--mb-body);
}
.mb-view-article :is(ul, ol) {
  padding-left: 1.5em;
}
.mb-view-article li + li,
.mb-view-article li > :is(ul, ol) {
  margin-top: 0.35em;
}
.mb-view-article li > :is(ul, ol) {
  margin-bottom: 0;
}
/* A quote stands in from the text, nothing drawn beside it */
.mb-view-article blockquote {
  margin-left: 0;
  padding-left: 1.5em;
}
.mb-view-article figure {
  margin: 1.5em 0;
}
.mb-view-article img {
  display: block;
  max-width: 100%;
  height: auto;
  margin: 0 auto;
  border-radius: var(--radius-xs);
  corner-shape: var(--corner-shape);
}
.mb-view-article a {
  color: inherit;
  text-decoration: underline;
  text-decoration-color: var(--border-strong);
  text-underline-offset: 0.18em;
}
.mb-view-article a:hover {
  text-decoration-color: currentColor;
}
.mb-view-article hr {
  margin: 2em 0;
  border: 0;
  border-top: 1px solid var(--border-subtle);
}
.mb-view-article code {
  font-size: 0.9em;
}
.mb-view-article pre {
  overflow-x: auto;
}
/* The passage a search found, opened at: tinted in graphite as the design system tints
   a passage (showPassage), with a little room above it when it's scrolled to. A
   browser without CSS Custom Highlights tints its blocks. */
.mb-view-article [data-line] {
  scroll-margin-top: var(--space-xl);
}
::highlight(mb-found) {
  background-color: var(--mark-echo);
}
.mb-view-article .is-found {
  background: var(--mark-echo);
}

/* The page. A long address or word breaks rather than pushing it wider. */
.mb-view-aside {
  min-height: 0;
  overflow-y: auto;
  padding: 0 var(--space-xl) var(--space-3xl);
  background: var(--bg-surface);
  box-shadow: -1px 0 0 var(--border-subtle);
  overflow-wrap: anywhere;
}
.mb-view-tools {
  position: sticky;
  top: 0;
  z-index: 2;
  display: flex;
  align-items: center;
  gap: var(--space-3xs);
  margin: 0 calc(var(--space-sm) * -1) var(--space-md);
  padding: var(--space-xs) 0;
  background: var(--bg-surface);
}
.mb-view-tools-gap {
  flex: 1;
}
.mb-page-head {
  margin: 0 0 var(--space-lg);
}
.mb-page-title {
  margin: 0;
  font: 600 var(--mb-title) / 1.25 var(--font-ui);
  letter-spacing: -0.012em;
  color: var(--text-ink);
  overflow-wrap: anywhere;
}
.mb-page-title-row {
  position: relative;
}
.mb-page-title.is-editable {
  position: relative;
  cursor: text;
  outline: none;
}
.mb-page-title[contenteditable="plaintext-only"]:empty::before {
  content: attr(data-placeholder);
  color: var(--text-ink-placeholder);
}
.mb-page-meta {
  margin: var(--space-2xs) 0 0;
  font: 400 var(--mb-small) / 1.45 var(--font-ui);
  color: var(--fg-muted);
}

/* Your tags and note */
.mb-mine {
  position: relative;
  margin: 0 0 var(--space-2xl);
}
.mb-tags {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-sm) var(--space-md);
  margin: 0 0 var(--space-md);
}
/* A tag is its ringed word, and the word is the control: under the pointer the pencil's
   strike runs through it, and a click takes the tag off */
.mb-tag {
  position: relative;
  display: inline-block;
  padding: 1px var(--space-3xs);
  border: 0;
  background: none;
  font: 400 var(--mb-body) / 1.3 var(--font-ui);
  color: var(--text-ink);
  cursor: pointer;
}
.mb-tag::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 50%;
  height: 6px;
  margin-top: -2px;
  background: var(--mark-strike-image) center / 100% 100% no-repeat;
  opacity: 0;
  transition: opacity var(--dur-fast) var(--ease-out);
  pointer-events: none;
}
.mb-tag:hover::after,
.mb-tag:focus-visible::after,
.mb-tag.is-going::after {
  opacity: 1;
}
.mb-tag:hover,
.mb-tag:focus-visible {
  color: var(--fg-muted);
}
.mb-tag-add {
  flex: 1 1 8em;
  min-width: 8em;
}
.mb-tag-input {
  width: 100%;
  padding: 1px 0;
  border: 0;
  background: none;
  outline: none;
  font: 400 var(--mb-body) / 1.3 var(--font-ui);
  color: var(--text-ink);
}
.mb-tag-input::placeholder {
  color: var(--fg-muted);
}
.mb-suggest {
  position: absolute;
  z-index: 5;
  left: 0;
  min-width: 220px;
  max-width: 100%;
}
.mb-suggest .ds-menu-item.is-active {
  background: var(--bg-hover);
}
/* The note: a ruled line in the face and size of the tags; the pencil draws the line
   while you write */
.mb-note {
  position: relative;
}
.mb-notes {
  display: block;
  width: 100%;
  box-sizing: border-box;
  margin: 0;
  padding: var(--space-2xs) 0;
  border: 0;
  border-bottom: 1px solid var(--border-subtle);
  background: transparent;
  outline: none;
  resize: none;
  overflow: hidden;
  font: 400 var(--mb-body) / 1.5 var(--font-ui);
  color: var(--text-ink);
  transition: border-color var(--dur-fast) var(--ease-out);
}
.mb-notes::placeholder {
  color: var(--fg-muted);
}
.mb-note.is-writing .mb-notes {
  border-bottom-color: transparent;
}

/* Its own words, the post it quotes, and what the agent wrote about it */
.mb-page-own {
  margin: 0 0 var(--space-2xl);
  font: 400 var(--mb-body) / 1.55 var(--font-ui);
  color: var(--text-ink);
  white-space: pre-line;
  overflow-wrap: anywhere;
}
.mb-page-quoted {
  margin: 0 0 var(--space-2xl);
  padding: var(--space-sm) var(--space-md);
  box-shadow: inset 0 0 0 1px var(--border-subtle);
  border-radius: var(--radius-sm);
  corner-shape: var(--corner-shape);
  font: 400 var(--mb-body) / 1.5 var(--font-ui);
  color: var(--text-ink);
  white-space: pre-line;
}
.mb-page-own + .mb-page-quoted {
  margin-top: calc(var(--space-lg) * -1);
}
.mb-page-quoted-by {
  display: block;
  margin: 0 0 var(--space-3xs);
  font: 400 var(--mb-small) / 1.45 var(--font-ui);
  color: var(--fg-muted);
}
.mb-page-label {
  margin: 0 0 var(--space-xs);
  font: 400 var(--mb-small) / 1.45 var(--font-ui);
  color: var(--fg-muted);
}
.mb-page-read {
  margin: 0 0 var(--space-2xl);
}
.mb-page-read p {
  margin: 0 0 var(--space-sm);
  font: 400 var(--mb-body) / 1.55 var(--font-ui);
  color: var(--text-ink);
}
.mb-page-ad {
  display: grid;
  grid-template-columns: max-content 1fr;
  gap: var(--space-xs) var(--space-md);
  margin: var(--space-md) 0 0;
}
.mb-page-ad dt {
  font: 400 var(--mb-small) / 1.7 var(--font-ui);
  color: var(--fg-muted);
}
.mb-page-ad dd {
  margin: 0;
  font: 400 var(--mb-body) / 1.5 var(--font-ui);
  color: var(--text-ink);
}

.mb-page-wait {
  min-height: 112px;
  margin: 0 0 var(--space-2xl);
}
.mb-like-grid {
  position: relative;
}

@media (max-width: 900px) {
  .mb-bar {
    flex-wrap: wrap;
    gap: var(--space-xs) var(--space-md);
  }
  .mb-search {
    flex-basis: 100%;
    max-width: none;
    order: -1;
  }
  /* The kinds scroll beside the tools, on one row */
  .mb-kinds,
  .mb-choosing {
    flex: 1 1 0%;
    min-width: 0;
  }
  :root {
    --mb-view-h: 68vh;
  }
  /* The picture, then the page, each its full height, scrolled together; never
     sideways. The page is a column at the reading measure, centred. */
  .mb-view {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: max-content max-content;
    align-content: start;
    overflow-x: hidden;
    overflow-y: auto;
  }
  .mb-view-media {
    padding: var(--space-sm);
  }
  .mb-view-aside {
    overflow: visible;
    padding: 0 max(var(--space-md), (100% - var(--mb-measure)) / 2) var(--space-2xl);
    box-shadow: 0 -1px 0 var(--border-subtle);
  }
  /* Its tools stick at the top, their ground across the whole width so nothing shows
     beside them as the picture scrolls under */
  .mb-view-tools {
    box-shadow: 0 0 0 100vmax var(--bg-surface);
    clip-path: inset(0 -100vmax);
  }
}

/* ── A YouTube video: YouTube's own cinema view ──────────────────────────────
   The player across the whole width, edge to edge on its dark stage, as tall as
   leaves the page's start in sight; the page below it in one column, its tools
   sticking at the top as it scrolls. YouTube's player letterboxes itself, so no
   paper shows at its sides. Fullscreen is the player's own (landscape, see
   moviebrain.js). */
.mb-view.is-cinema {
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: max-content max-content;
  align-content: start;
  overflow-x: hidden;
  overflow-y: auto;
}
.mb-view.is-cinema .mb-view-media {
  display: block;
  padding: 0;
  overflow: visible;
  background: oklch(0.12 0.005 60);
}
.mb-view.is-cinema .mb-view-media > .mb-view-embed.is-youtube {
  width: 100%;
  max-width: none;
  height: min(56.25vw, calc(100vh - 7rem));
  height: min(56.25vw, calc(100dvh - 7rem));
  max-height: none;
  border-radius: 0;
  box-shadow: none;
}
.mb-view-embed.is-youtube > iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}
.mb-view.is-cinema .mb-travel {
  display: none;
}
.mb-view.is-cinema .mb-view-aside {
  overflow: visible;
  padding: 0 max(var(--space-md), (100% - var(--mb-measure)) / 2) var(--space-3xl);
  background: none;
  box-shadow: none;
}
.mb-view.is-cinema .mb-view-tools {
  background: var(--bg-canvas);
  box-shadow: 0 0 0 100vmax var(--bg-canvas);
  clip-path: inset(0 -100vmax);
}
/* On a phone, the player is the screen's width at its own shape */
.is-touch .mb-view.is-cinema .mb-view-media > .mb-view-embed.is-youtube {
  height: auto;
  aspect-ratio: 16 / 9;
}
