/* ============================================================================
   Merit — components
   Every control used by both surfaces, under the `m-` namespace so the legacy
   stylesheets can coexist during the view-by-view migration. Modifiers are
   data attributes, matching the existing app's `data-tone` convention.

   Copied into web/ and landing/ by `npm run design:sync`; edit it here.
   ========================================================================= */

/* ------------------------------------------------------------------ layout */
.m-stack { display: grid; gap: var(--s-3); align-content: start; }
.m-stack-1 { gap: var(--s-1); }
.m-stack-2 { gap: var(--s-2); }
.m-stack-5 { gap: var(--s-5); }
.m-stack-6 { gap: var(--s-6); }
.m-row { display: flex; align-items: center; gap: var(--s-2); flex-wrap: wrap; }
.m-row-3 { gap: var(--s-3); }
.m-between { display: flex; align-items: center; justify-content: space-between; gap: var(--s-3); }
.m-grow { flex: 1 1 auto; min-width: 0; }
.m-center { justify-items: center; text-align: center; }
.m-wrap { max-width: var(--shell-max); margin-inline: auto; padding-inline: var(--s-5); }

/* -------------------------------------------------------------------- text */
.m-label {
  font-size: var(--t-3);
  font-weight: var(--w-semi);
  color: var(--label-2);
  letter-spacing: var(--track-body);
}
.m-kicker {
  font-size: var(--t-2);
  font-weight: var(--w-semi);
  color: var(--label-3);
  letter-spacing: 0.01em;
}
.m-copy { font-size: var(--t-4); color: var(--label-2); line-height: var(--lh-body); }
.m-copy-sm { font-size: var(--t-3); color: var(--label-2); line-height: 1.5; }
.m-dim { color: var(--label-3); }
.m-num { font-family: var(--font-num); font-variant-numeric: tabular-nums; font-size: var(--t-3); }
.m-balance { text-wrap: balance; }
.m-pretty { text-wrap: pretty; }
.m-prose { max-width: 68ch; }
.m-prose p + p { margin-top: var(--s-3); }

/* ----------------------------------------------------------------- buttons
   Minimum target is 44px. Press state is a subtle scale, never a colour jolt. */
.m-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--s-2);
  min-height: 44px;
  padding: 0 var(--s-5);
  border-radius: var(--r-md);
  font-size: var(--t-4);
  font-weight: var(--w-semi);
  letter-spacing: var(--track-body);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease),
              transform var(--t-press) var(--ease),
              opacity var(--t-fast) var(--ease);
}
.m-btn:active { transform: scale(0.975); }
.m-btn:disabled, .m-btn[aria-disabled="true"] { opacity: 0.42; pointer-events: none; }

.m-btn-primary { background: var(--accent); color: var(--accent-ink); }
.m-btn-primary:hover { background: var(--accent-press); }

.m-btn-secondary { background: var(--surface-3); color: var(--label); }
.m-btn-secondary:hover { background: var(--surface-4); }

.m-btn-outline {
  background: var(--surface-1);
  color: var(--label);
  border: 1px solid var(--line-strong);
}
.m-btn-outline:hover { background: var(--surface-2); }

.m-btn-ghost { background: transparent; color: var(--accent); padding: 0 var(--s-3); }
.m-btn-ghost:hover { background: var(--accent-soft); }

.m-btn-danger { background: transparent; color: var(--danger); padding: 0 var(--s-3); }
.m-btn-danger:hover { background: var(--danger-soft); }

.m-btn-sm { min-height: 34px; padding: 0 var(--s-3); font-size: var(--t-3); border-radius: var(--r-sm); }
.m-btn-lg { min-height: 52px; padding: 0 var(--s-6); font-size: var(--t-5); border-radius: var(--r-lg); }
.m-btn-block { width: 100%; }
.m-btn-icon { min-height: 44px; min-width: 44px; padding: 0; border-radius: var(--r-md); }

/* ------------------------------------------------------------------ fields */
.m-field { display: grid; gap: var(--s-2); }
/* Field labels are bold and carry the full label colour: at the secondary
   step and a semi weight they read as placeholder text on both themes. */
.m-field > span,
.m-field-label { font-size: var(--t-3); font-weight: var(--w-bold); color: var(--label); }
.m-input, .m-textarea, .m-select {
  width: 100%;
  min-height: 44px;
  padding: var(--s-3);
  background: var(--input-bg);
  color: var(--label);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  font-size: var(--t-4);
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.m-textarea { padding: var(--s-3); line-height: var(--lh-body); }
/* Long-form writing — an evidence statement, pasted notes. It is set in the
   document face (the same one the CV is written in) and given a roomier
   measure, because these fields hold paragraphs, not answers. */
.m-textarea-prose {
  font-family: var(--font-doc);
  font-size: var(--t-4);
  line-height: 1.65;
  padding: var(--s-4) var(--s-5);
}
.m-input::placeholder, .m-textarea::placeholder { color: var(--label-3); }
.m-input:hover, .m-textarea:hover { border-color: var(--label-3); }
.m-field-hint { font-size: var(--t-2); color: var(--label-3); }
.m-field[data-invalid="true"] .m-input,
.m-field[data-invalid="true"] .m-textarea { border-color: var(--danger); }

/* Native file input styled as a dashed drop target. */
.m-drop {
  display: grid;
  gap: var(--s-2);
  justify-items: center;
  padding: var(--s-6) var(--s-4);
  border: 1.5px dashed var(--line-strong);
  border-radius: var(--r-md);
  background: var(--surface-2);
  text-align: center;
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.m-drop:hover, .m-drop[data-over="true"] { border-color: var(--accent); background: var(--accent-soft); }
.m-drop svg { color: var(--accent); }

/* --------------------------------------------------------------- segmented */
.m-seg {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  background: var(--surface-3);
  border-radius: var(--r-md);
}
.m-seg > button, .m-seg > a {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  min-height: 32px;
  padding: 0 var(--s-3);
  border-radius: var(--r-sm);
  font-size: var(--t-3);
  font-weight: var(--w-medium);
  color: var(--label-2);
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.m-seg > [aria-current="page"],
.m-seg > [aria-pressed="true"] {
  background: var(--surface-1);
  color: var(--label);
  font-weight: var(--w-semi);
  box-shadow: var(--elev-1);
}

/* ------------------------------------------------------------------- chips */
.m-chip {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px var(--s-2);
  border-radius: var(--r-full);
  background: var(--chip-bg);
  color: var(--label-2);
  font-size: var(--t-2);
  font-weight: var(--w-medium);
  white-space: nowrap;
}
.m-chip svg { width: 12px; height: 12px; }
.m-chip[data-tone="ok"], .m-chip.m-chip-ok { background: var(--success-soft); color: var(--success); }
.m-chip[data-tone="warn"], .m-chip.m-chip-warn { background: var(--warn-soft); color: var(--warn); }
.m-chip[data-tone="danger"] { background: var(--danger-soft); color: var(--danger); }
.m-chip[data-tone="info"] { background: var(--info-soft); color: var(--info); }
.m-chip[data-tone="accent"], .m-chip.m-chip-accent { background: var(--accent-soft); color: var(--accent); }
.m-chip-lg { padding: var(--s-2) var(--s-4); font-size: var(--t-3); }

/* ------------------------------------------------------------------- cards */
.m-card {
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-card);
}
.m-card-pad { padding: var(--s-4); }
.m-card-flush { box-shadow: none; background: var(--surface-2); }
.m-panel {
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  padding: var(--s-4);
}

/* --------------------------------------------------------------- app chrome */
.m-topbar {
  position: sticky;
  top: 0;
  z-index: 40;
  display: flex;
  align-items: center;
  gap: var(--s-3);
  min-height: var(--topbar-h);
  padding: var(--s-2) var(--s-4);
  padding-top: calc(var(--s-2) + var(--safe-top));
  background: rgb(var(--bar-rgb) / var(--bar-alpha));
  backdrop-filter: var(--material-blur);
  -webkit-backdrop-filter: var(--material-blur);
  border-bottom: 1px solid var(--line);
}
.m-topbar-title {
  margin-right: auto;
  font-size: var(--t-5);
  font-weight: var(--w-semi);
  letter-spacing: var(--track-card);
}

.m-tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  z-index: 45;
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: 1fr;
  padding: var(--s-2) var(--s-2) calc(var(--s-2) + var(--safe-bottom));
  background: rgb(var(--bar-rgb) / var(--bar-alpha));
  backdrop-filter: var(--material-blur);
  -webkit-backdrop-filter: var(--material-blur);
  border-top: 1px solid var(--line);
}
.m-tabbar a, .m-tabbar button {
  display: grid;
  justify-items: center;
  gap: 3px;
  min-height: 44px;
  padding-top: 2px;
  color: var(--label-3);
  font-size: 10px;
  font-weight: var(--w-medium);
  letter-spacing: 0.005em;
  transition: color var(--t-fast) var(--ease);
}
.m-tabbar svg { width: 24px; height: 24px; }
.m-tabbar a, .m-tabbar button { min-height: 44px; }
.m-tabbar [aria-current="page"] { color: var(--accent); }
/* Reserve room so the fixed bar never covers the end of a screen. */
.m-has-tabbar { padding-bottom: calc(var(--tabbar-h) + var(--safe-bottom) + var(--s-4)); }

@media (min-width: 900px) {
  .m-tabbar {
    position: sticky;
    top: calc(var(--topbar-h) + var(--safe-top));
    grid-auto-flow: row;
    grid-auto-columns: auto;
    height: auto;
    padding: var(--s-3);
    border-top: 0;
    border-right: 1px solid var(--line);
  }
  .m-tabbar a, .m-tabbar button {
    grid-auto-flow: column;
    grid-template-columns: 20px 1fr;
    justify-items: start;
    align-items: center;
    gap: var(--s-3);
    min-height: 40px;
    padding: 0 var(--s-3);
    border-radius: var(--r-sm);
    font-size: var(--t-3);
  }
  .m-tabbar svg { width: 20px; height: 20px; }
  .m-tabbar [aria-current="page"] { background: var(--accent-soft); }
  .m-has-tabbar { padding-bottom: var(--s-6); }
}

/* ----------------------------------------------------------------- avatars */
.m-avatar {
  display: grid;
  place-items: center;
  width: 32px; height: 32px;
  border-radius: var(--r-full);
  background: var(--accent-soft);
  color: var(--accent);
  border: 1px solid var(--accent-edge);
  font-size: var(--t-2);
  font-weight: var(--w-bold);
  letter-spacing: 0.01em;
}
.m-avatar-btn { border-radius: var(--r-full); min-height: 44px; min-width: 44px; display: grid; place-items: center; }

/* ------------------------------------------------------------------ lists */
.m-list { display: grid; gap: var(--s-2); }
.m-rowitem {
  display: flex;
  align-items: flex-start;
  gap: var(--s-3);
  padding: var(--s-4);
  background: var(--surface-1);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
  transition: border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.m-rowitem-interactive { cursor: pointer; }
.m-rowitem-interactive:hover { border-color: var(--line-strong); }
.m-rowitem[data-tone="warn"] { background: var(--surface-2); border-color: var(--warn-soft); }
.m-sep { height: 1px; background: var(--line); }

/* ---------------------------------------------------------------- progress */
.m-progress {
  height: 6px;
  border-radius: var(--r-full);
  background: var(--track);
  overflow: hidden;
}
.m-progress > i {
  display: block;
  height: 100%;
  width: 0;
  border-radius: var(--r-full);
  background: var(--accent);
  transition: width var(--t-slow) var(--ease);
}

/* ------------------------------------------------------------------ toasts */
.m-toast-host {
  position: fixed;
  left: 50%;
  transform: translateX(-50%);
  bottom: calc(var(--tabbar-h) + var(--safe-bottom) + var(--s-4));
  z-index: 120;
  display: grid;
  gap: var(--s-2);
  width: min(420px, calc(100vw - var(--s-8)));
  pointer-events: none;
}
.m-toast {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding: var(--s-3) var(--s-4);
  background: rgb(var(--sheet-rgb) / 0.96);
  backdrop-filter: var(--material-blur);
  -webkit-backdrop-filter: var(--material-blur);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-lg);
  box-shadow: var(--shadow-float);
  font-size: var(--t-3);
  pointer-events: auto;
  animation: m-toast-in var(--t-base) var(--spring) both;
}
.m-toast[data-tone="warn"] { border-color: var(--warn-soft); }
.m-toast .m-btn { margin-left: auto; }
@keyframes m-toast-in {
  from { opacity: 0; transform: translateY(8px) scale(0.98); }
  to { opacity: 1; transform: none; }
}

/* ------------------------------------------------------------------ sheets */
.m-sheet-backdrop {
  position: fixed;
  inset: 0;
  z-index: 100;
  background: rgb(0 0 0 / 0.42);
  backdrop-filter: blur(2px);
  animation: m-fade var(--t-base) var(--ease) both;
}
.m-sheet {
  position: fixed;
  left: 50%;
  bottom: 0;
  z-index: 101;
  transform: translateX(-50%);
  width: min(560px, 100vw);
  max-height: min(86vh, 780px);
  overflow-y: auto;
  padding: var(--s-5) var(--s-4) calc(var(--s-5) + var(--safe-bottom));
  background: rgb(var(--sheet-rgb) / var(--sheet-alpha));
  backdrop-filter: var(--material-blur);
  -webkit-backdrop-filter: var(--material-blur);
  border: 1px solid var(--line-strong);
  border-bottom: 0;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  box-shadow: var(--shadow-float);
  animation: m-sheet-up var(--t-base) var(--spring) both;
}
.m-sheet-grip {
  width: 36px; height: 4px;
  margin: 0 auto var(--s-4);
  border-radius: var(--r-full);
  background: var(--line-strong);
}
@media (min-width: 900px) {
  .m-sheet {
    left: auto; right: var(--s-5);
    bottom: var(--s-5);
    transform: none;
    border-radius: var(--r-xl);
    border-bottom: 1px solid var(--line-strong);
  }
}
@keyframes m-sheet-up {
  from { opacity: 0; transform: translate(-50%, 16px); }
  to { opacity: 1; transform: translate(-50%, 0); }
}
@media (min-width: 900px) {
  @keyframes m-sheet-up {
    from { opacity: 0; transform: translateY(16px) scale(0.98); }
    to { opacity: 1; transform: none; }
  }
}
@keyframes m-fade { from { opacity: 0; } to { opacity: 1; } }

/* ------------------------------------------------------------------ dialog */
.m-dialog {
  width: min(560px, calc(100vw - var(--s-6)));
  padding: 0;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-2xl);
  background: var(--surface-1);
  color: var(--label);
  box-shadow: var(--shadow-float);
}
.m-dialog::backdrop { background: rgb(0 0 0 / 0.45); backdrop-filter: blur(2px); }
.m-dialog-body { padding: var(--s-5); display: grid; gap: var(--s-4); }
.m-dialog-actions { display: flex; justify-content: flex-end; gap: var(--s-2); }

/* ------------------------------------------------------------------- empty */
.m-empty {
  display: grid;
  gap: var(--s-3);
  justify-items: start;
  padding: var(--s-6);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-lg);
}
.m-empty h3 { font-size: var(--t-4); }

/* ------------------------------------------------------------------- notes */
/* A note is a paragraph, not a row of columns.
   It was a flex container, which silently turned every contiguous run of text
   into its own item: "Your plan usage is used up. <a>Add extra usage</a> to keep
   interviewing." laid out as three columns, and <strong>+<p>+<ul> notes stacked
   sideways. Block flow lets inline links sit in the sentence and block children
   stack; the spacing rule keeps the stacked ones readable. */
.m-note {
  display: block;
  padding: var(--s-3) var(--s-4);
  border-radius: var(--r-md);
  background: var(--surface-2);
  border: 1px solid var(--line);
  font-size: var(--t-3);
  color: var(--label-2);
}
.m-note > * + * { margin-top: var(--s-2); }
.m-note a { color: var(--accent-text); text-decoration: underline; text-underline-offset: 2px; }
.m-note[data-tone="ok"] { background: var(--success-soft); border-color: transparent; color: var(--success); }
.m-note[data-tone="warn"] { background: var(--warn-soft); border-color: transparent; color: var(--warn); }
.m-note[data-tone="danger"] { background: var(--danger-soft); border-color: transparent; color: var(--danger); }
.m-note[data-tone="info"] { background: var(--info-soft); border-color: transparent; color: var(--info); }

/* --------------------------------------------------------------- skeletons */
.m-skel {
  border-radius: var(--r-sm);
  background: linear-gradient(90deg, var(--surface-3) 25%, var(--surface-2) 37%, var(--surface-3) 63%);
  background-size: 400% 100%;
  animation: m-shimmer 1.6s linear infinite;
}
@keyframes m-shimmer { from { background-position: 100% 0; } to { background-position: 0 0; } }

/* ---------------------------------------------------------- busy indicator */
.m-busy {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 2px;
  z-index: 60;
  overflow: hidden;
  background: transparent;
}
.m-busy::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 40%;
  background: var(--accent);
  border-radius: var(--r-full);
  animation: m-busy 1.1s var(--ease) infinite;
}
@keyframes m-busy {
  from { transform: translateX(-100%); }
  to { transform: translateX(250%); }
}

/* ------------------------------------------------------------- offline bar */
.m-offline {
  padding: var(--s-2) var(--s-4);
  background: var(--warn-soft);
  color: var(--warn);
  font-size: var(--t-3);
  text-align: center;
}

/* ------------------------------------------------------------ CV document
   A separate surface: paper, not app chrome. Deliberately light in both
   themes so what you edit is what prints. */
.m-doc {
  background: var(--doc-bg);
  color: var(--doc-ink);
  border-radius: var(--r-lg);
  padding: var(--s-6) var(--s-5);
  box-shadow: var(--shadow-card);
  font-family: var(--font-doc);
  font-size: var(--t-3);
  line-height: 1.5;
}
.m-doc-name { font-size: var(--t-7); font-weight: var(--w-bold); letter-spacing: -0.03em; }
.m-doc-role { font-size: var(--t-4); color: #4a5260; margin-top: 2px; }
.m-doc-contact { font-size: var(--t-2); color: #6b7280; margin-top: var(--s-3); line-height: 1.6; }
.m-doc-sec {
  margin-top: var(--s-5);
  padding-top: var(--s-3);
  border-top: 1px solid #e7e9ec;
  font-family: var(--font);
  font-size: var(--t-2);
  font-weight: var(--w-bold);
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: #3c4453;
}
.m-doc-item { margin-top: var(--s-3); }
.m-doc-item .m-doc-role-title { font-size: var(--t-3); font-weight: var(--w-bold); color: var(--doc-ink); }
.m-doc-item .m-doc-org { font-size: var(--t-2); color: #6b7280; }
.m-doc-bullets { margin-top: var(--s-2); padding-left: var(--s-4); }
.m-doc-bullets li {
  list-style: disc;
  font-size: var(--t-3);
  color: #333a47;
  line-height: 1.5;
  margin-bottom: 3px;
}

/* In-place editable region inside the document. */
.m-editable {
  border-radius: var(--r-xs);
  outline: 2px solid transparent;
  outline-offset: 2px;
  transition: background var(--t-fast) var(--ease), outline-color var(--t-fast) var(--ease);
  cursor: text;
}
.m-editable:hover { background: var(--accent-soft); }
.m-editable[data-editing="true"],
.m-editable:focus-visible {
  outline-color: var(--accent);
  background: #fff8ec;
}
.m-editable-row { display: flex; align-items: flex-start; gap: var(--s-3); }
.m-editable-check {
  flex: 0 0 auto;
  width: 20px; height: 20px;
  margin-top: 3px;
  border-radius: var(--r-xs);
  border: 1.5px solid var(--line-strong);
  display: grid;
  place-items: center;
  background: var(--surface-1);
}
.m-editable-check[aria-pressed="true"] { background: var(--accent); border-color: var(--accent); color: var(--accent-ink); }

/* ------------------------------------------------------- coverage / mapping */
.m-coverage { display: grid; gap: var(--s-2); }
.m-coverage-row {
  display: grid;
  gap: var(--s-2);
  padding: var(--s-3);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: var(--r-md);
}
.m-coverage-bar { height: 4px; border-radius: var(--r-full); background: var(--track); overflow: hidden; }
.m-coverage-bar > i { display: block; height: 100%; border-radius: var(--r-full); }
.m-coverage-bar[data-tone="ok"] > i { background: var(--success); }
.m-coverage-bar[data-tone="warn"] > i { background: var(--warn); }
.m-coverage-bar[data-tone="danger"] > i { background: var(--danger); }

/* -------------------------------------------------------------- usage meter */
.m-usage { display: grid; gap: var(--s-2); }
.m-usage-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-3); }
.m-usage-pct { font-size: var(--t-6); font-weight: var(--w-bold); letter-spacing: var(--track-heading); font-variant-numeric: tabular-nums; }
.m-usage-bar { height: 8px; border-radius: var(--r-full); background: var(--track); overflow: hidden; }
.m-usage-bar > i { display: block; height: 100%; border-radius: var(--r-full); background: var(--accent); transition: width var(--t-slow) var(--ease); }
.m-usage-bar[data-tone="warn"] > i { background: var(--warn); }
.m-usage-bar[data-tone="danger"] > i { background: var(--danger); }

/* ------------------------------------------------------------------- mark */
.m-mark { display: block; color: var(--accent); }
.m-wordmark { font-size: var(--t-5); font-weight: var(--w-bold); letter-spacing: -0.03em; }
.m-lockup { display: inline-flex; align-items: center; gap: var(--s-2); }

/* ------------------------------------------------ signature motion atoms
   Each is a named, opt-out animation. Motion is used to make a state change
   legible, never to decorate. */
.m-settle { animation: m-settle var(--t-slow) var(--spring) both; }
@keyframes m-settle {
  from { opacity: 0; transform: translateY(-6px) scale(0.985); }
  to { opacity: 1; transform: none; }
}
.m-rise { animation: m-rise var(--t-base) var(--ease) both; }
@keyframes m-rise {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: none; }
}
/* ---------------------------------------------------------------- compose
   The signature motion for "Merit wrote this": on a rebuild the lines settle
   into the page in document order rather than appearing all at once. The
   stagger is set as a per-element delay by the caller, so the motion layer
   stays declarative and the view decides the order. */
[data-compose="true"] .cv-editable,
[data-compose="true"] .m-compose-line {
  animation: m-compose var(--t-base) var(--ease) both;
  animation-delay: var(--stagger, 0ms);
}
@keyframes m-compose {
  from { opacity: 0; transform: translateY(6px); }
  to { opacity: 1; transform: none; }
}

/* Lift: sheets, dialogs and the account panel rise on open. */
.m-lift { animation: m-lift var(--t-base) var(--spring) both; }
@keyframes m-lift {
  from { opacity: 0; transform: translateY(14px) scale(0.985); }
  to { opacity: 1; transform: none; }
}
dialog.m-dialog[open],
dialog.editor-dialog[open] { animation: m-lift var(--t-base) var(--spring) both; }
dialog::backdrop { animation: m-fade var(--t-base) var(--ease) both; }
.m-press { transition: transform var(--t-press) var(--ease); }
.m-press:active { transform: scale(0.975); }

/* Reveal-on-scroll for marketing. Visible by default so a missing observer
   can never leave a blank section — the previous site's failure mode. */
.m-reveal { opacity: 1; }
.js .m-reveal { opacity: 0; transform: translateY(10px); }
.js .m-reveal[data-shown="true"] {
  opacity: 1;
  transform: none;
  transition: opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
@media (prefers-reduced-motion: reduce) {
  .js .m-reveal { opacity: 1; transform: none; }
}

/* ------------------------------------------------------ target-size floors
   Every interactive control is at least 44x44 CSS px. Icon buttons get the
   size via the box; text controls get it via min-height. */
/* Compact controls still carry a 44px hit target: the visual box stays small,
   the tappable area does not.

   `!important` on the segmented control is load-bearing and was verified by
   removing it: the legacy app stylesheet sets a min-height on `.btn` from a
   four-class selector, which outranks this one and collapsed the vault filters
   to 36px. Drop the flag only when the legacy `.btn` rule is deleted from
   web/styles.css. The `.m-btn-sm` floor does not need a flag. */
.m-seg > button,
.m-seg > a { min-height: 44px !important; }
.m-btn-sm { min-height: 44px; padding-inline: var(--s-4); }
.m-icon-44 {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  border-radius: var(--r-md);
}
.m-skip {
  position: absolute;
  left: var(--s-4);
  top: var(--s-4);
  z-index: 200;
  padding: var(--s-3) var(--s-4);
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  background: var(--surface-1);
  color: var(--label);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-float);
  transform: translateY(calc(-100% - var(--s-6)));
  transition: transform var(--t-fast) var(--ease);
}
.m-skip:focus { transform: none; }
