/* ══════════════════════════════════════════════════════════════
   518.PLUS components — the ONLY shared visual vocabulary.
   Pages compose these; page CSS (518.css / samelabs.css) does
   page layout only. Every component uses tokens.css variables.
   ══════════════════════════════════════════════════════════════ */

/* ── Element control defaults (moved from 518.css — one baseline) ──
   16px floor: iOS/Android auto-zoom any focused input <16px;
   font-family: inherit — UA default differs from page font otherwise.
   NOTE: this selector must stay UNPREFIXED. A prior revision glued the
   comment to `.controls`, silently scoping the floor to `.controls
   input` — every input elsewhere kept UA ~13px and iOS zoomed on focus. */
input, select, textarea {
  font-family: inherit;
  font-size: 16px;
}
select { width: auto; margin-top: 0; }

/* Legacy element baseline (auth surfaces pre-date .btn): brand pill. */
.x-login, button { border: 0; background: var(--brand); color: var(--brand-ink); border-radius: var(--r-full); padding: 11px 22px; font-size: var(--fs-base); font-weight: 700; cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; gap: var(--s2); min-height: 40px; transition: opacity var(--ease), background var(--ease), transform var(--ease-in); -webkit-tap-highlight-color: transparent; }
@media (hover:hover) and (pointer:fine) { button:hover { background: var(--brand-strong); } }
.x-login:active, button:active { transform: scale(0.96); }
.user-dropdown a:active, .user-dropdown button:active { transform: none; } /* menu rows must not wobble */
@media (hover:hover) and (pointer:fine) { .x-login:hover, button:hover { opacity: .85; } }
.x-login.loading { pointer-events: none; opacity: .7; }
button:disabled { opacity: .4; cursor: not-allowed; }
button svg { width: 18px; height: 18px; display: block; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; fill: none; }
.x-glyph { font-family: ui-serif, Georgia, "Times New Roman", serif; font-size: 18px; line-height: 1; font-weight: 800; }
/* X brand button (auth surfaces only): black plate, white ink — narrow
   selector, global button palette untouched. */
.auth-x-wrap .x-login { background: var(--ink); color: var(--brand-ink); }
@media (hover:hover) and (pointer:fine) { .auth-x-wrap .x-login:hover { background: var(--ink-hover); opacity: 1; } }
.auth-x-wrap .x-login:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

/* ── Buttons ─────────────────────────────────────────────────
   .btn base; variants primary/secondary/ghost/danger; sizes
   .btn-sm/.btn-lg; .btn-icon = square icon-only (REQUIRES
   aria-label + title); .is-loading shows a spinner and blocks. */
/* Variant classes are STANDALONE (usable without the .btn base) — the
   base block applies to every variant so page-level legacy callers and
   composite "btn btn-primary" render identically. */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: var(--s2); height: 40px; padding: 0 var(--s4);
  border: var(--border-w) solid transparent; border-radius: var(--r-sm);
  font: inherit; font-size: var(--fs-base); font-weight: 650;
  cursor: pointer; text-decoration: none; white-space: nowrap;
  transition: background var(--ease), border-color var(--ease),
    color var(--ease), transform var(--ease-in), opacity var(--ease);
  background: none; color: var(--ink);
}
.btn:active { transform: scale(0.97); }
.btn:disabled, .btn[aria-disabled="true"] { opacity: 0.55; cursor: default; pointer-events: none; }
.btn svg {
  width: 18px; height: 18px; stroke: currentColor; stroke-width: 1.75;
  fill: none; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0;
}

.btn.btn-primary, .btn.btn-p, a.btn-primary, a.btn-p {
  background: var(--ink); border-color: var(--ink); color: var(--brand-ink);
}
@media (hover:hover) and (pointer:fine) { .btn-primary:hover, .btn-p:hover { background: var(--ink-hover); border-color: var(--ink-hover); } }
.btn.btn-b, a.btn-b { background: var(--brand); border-color: var(--brand); color: var(--brand-ink); box-shadow: 0 6px 16px -6px rgba(255, 77, 77, 0.6); }
@media (hover:hover) and (pointer:fine) { .btn-primary:hover { background: var(--brand-strong); border-color: var(--brand-strong); } }

.btn-secondary { background: var(--card); border-color: var(--line-2); color: var(--ink); }
@media (hover:hover) and (pointer:fine) { .btn-secondary:hover { border-color: var(--ink-2); } }

.btn-ghost { background: none; color: var(--ink-2); }
@media (hover:hover) and (pointer:fine) { .btn-ghost:hover { background: var(--gray-100); color: var(--ink); } }

.btn-danger { background: var(--danger); border-color: var(--danger); color: var(--brand-ink); }
@media (hover:hover) and (pointer:fine) { .btn-danger:hover { background: var(--danger-strong); border-color: var(--danger-strong); } }
.btn-danger-soft { background: var(--danger-50); border-color: transparent; color: var(--danger); }
@media (hover:hover) and (pointer:fine) { .btn-danger-soft:hover { border-color: var(--danger); } }

.btn-sm { height: 32px; padding-inline: var(--s3); font-size: var(--fs-sm); }
.btn-sm svg { width: 15px; height: 15px; }
.btn-lg { height: 48px; padding-inline: var(--s5); font-size: var(--fs-md); }

.btn-icon { width: 40px; padding-inline: 0; }
.btn-icon.btn-sm { width: 32px; }

.btn.is-loading {
  position: relative; color: transparent !important; pointer-events: none;
}
.btn.is-loading::after {
  content: ""; position: absolute; inset-block-start: 50%; inset-inline-start: 50%;
  width: 18px; height: 18px; margin: -9px 0 0 -9px;
  border: 2px solid rgba(255, 255, 255, 0.35); border-top-color: currentColor;
  border-radius: 50%; color: var(--brand);
  animation: btn-spin 0.7s linear infinite;
}
.btn.btn-secondary.is-loading::after { border-color: rgba(15,20,25,0.15); border-top-color: var(--ink); }
@keyframes btn-spin { to { transform: rotate(360deg); } }

/* ── Cards ─────────────────────────────────────────────────── */
.card {
  background: var(--card); border: var(--border-w) solid var(--line);
  border-radius: var(--r-lg); box-shadow: var(--sh-1);
}
.card-pad { padding: var(--s4); }
@media (min-width: 600px) { .card-pad { padding: var(--s5); } }
.card-head {
  display: flex; align-items: center; gap: var(--s3);
  padding: var(--s4) var(--s5); border-block-end: var(--border-w) solid var(--line);
}
.card-head h2 { font-size: var(--fs-md); font-weight: 700; }

/* ── Form controls ─────────────────────────────────────────── */
.input, .textarea, .select {
  width: 100%; border: var(--border-w) solid var(--line-2);
  border-radius: var(--r-sm); padding: 10px var(--s3);
  font: inherit; font-size: var(--fs-base); color: var(--ink);
  background: var(--card); transition: border-color var(--ease);
}
.input:focus-visible, .textarea:focus-visible, .select:focus-visible {
  outline: 2px solid var(--brand); outline-offset: 0; border-color: var(--brand);
}
.input::placeholder, .textarea::placeholder { color: var(--ink-3); }
.textarea { resize: vertical; min-height: 96px; line-height: var(--lh-loose); }
.select { appearance: none; cursor: pointer;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23536471' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right var(--s3) center;
  background-size: 14px; padding-inline-end: var(--s6);
}
[dir="rtl"] .select { background-position: left var(--s3) center; }
.field { display: flex; flex-direction: column; gap: var(--s1); }
.field > .field-label { font-size: var(--fs-sm); font-weight: 650; color: var(--ink); }
.field .field-req { color: var(--brand); }
.field .field-note { font-size: var(--fs-sm); color: var(--ink-2); }

/* checkbox row */
.check { display: flex; align-items: center; gap: var(--s2); font-size: var(--fs-base); cursor: pointer; }
.check input { width: 17px; height: 17px; accent-color: var(--brand); }

/* switch */
.switch { position: relative; display: inline-flex; align-items: center; width: 40px; height: 22px; cursor: pointer; }
.switch input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.switch .switch-track { position: absolute; inset: 0; background: var(--gray-300); border-radius: var(--r-full); transition: background var(--ease); }
.switch .switch-track::after {
  content: ""; position: absolute; inset-block-start: 2px; inset-inline-start: 2px;
  width: 18px; height: 18px; border-radius: 50%; background: var(--card);
  box-shadow: var(--sh-1); transition: transform var(--ease);
}
.switch input:checked + .switch-track { background: var(--brand); }
.switch input:checked + .switch-track::after { transform: translateX(18px); }
[dir="rtl"] .switch input:checked + .switch-track::after { transform: translateX(-18px); }

/* ── File entry (one row: identity + meta + actions) ─────────
   Used by input attachments, result file items and the /f page. */
.file-row {
  display: flex; align-items: center; gap: var(--s3); text-align: start;
  border: var(--border-w) solid var(--line); border-radius: var(--r);
  padding: var(--s2) var(--s3); background: var(--card);
}
.file-thumb {
  width: 40px; height: 40px; border-radius: var(--r-xs); object-fit: cover;
  flex-shrink: 0; background: var(--sunk);
}
.file-thumb-glyph { display: inline-flex; align-items: center; justify-content: center; }
.file-thumb-glyph svg { width: 18px; height: 18px; stroke: var(--ink-2); stroke-width: 1.75; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.file-name { flex: 1; min-width: 0; font-size: var(--fs-base); font-weight: 650; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.file-meta { font-size: var(--fs-sm); color: var(--ink-2); flex-shrink: 0; }
.file-remove {
  display: inline-flex; align-items: center; justify-content: center;
  width: 28px; height: 28px; border: 0; border-radius: var(--r-xs);
  background: none; color: var(--ink-3); cursor: pointer;
}
.file-remove svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; }
@media (hover:hover) and (pointer:fine) { .file-remove:hover { color: var(--danger); background: var(--danger-50); } }

/* ── Result card (v2 "out") + items — the tool-page result area AND
   the /r result page share this structure: .out > .out-h + .out-b >
   .linkbar + items. Structure classes rs-* stay stable (/r page
   server-side markup + browser suites ride on them). ── */
.out { overflow: hidden; box-shadow: var(--sh-2); }
.out-h {
  display: flex; align-items: center; gap: 10px; padding: 16px 20px;
  border-block-end: var(--border-w) solid var(--line);
}
.out-h .ok {
  width: 22px; height: 22px; border-radius: 50%; background: var(--ok);
  color: var(--brand-ink); display: grid; place-items: center; flex: none;
}
.out-h .ok svg { width: 13px; height: 13px; stroke: currentColor; stroke-width: 3; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.out-h b { font-weight: 650; font-size: var(--fs-md); }
.out-h .t { font-size: var(--fs-xs); color: var(--ink-3); margin-inline-start: auto; display: inline-flex; gap: var(--s2); align-items: center; }
.out-b { padding: 20px; display: flex; flex-direction: column; gap: 14px; }

/* Lightweight one-line link strip: no heavy border, no fill — a quiet
   bottom line only; the URL is tertiary text on a single ellipsized
   line and the copy action is a compact secondary button (visual
   weight stays below the primary actions). */
.linkbar {
  display: flex; align-items: center; gap: 8px; padding: 5px 2px 5px 12px;
  border-radius: 0; background: none;
  border: 0; border-bottom: var(--border-w) solid var(--line);
}
.linkbar > svg { width: 15px; height: 15px; color: var(--ink-3); stroke: currentColor; stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; flex: none; }
.linkbar span {
  flex: 1; min-width: 0; font-family: var(--font-mono); font-size: var(--fs-sm);
  color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.linkbar .btn { flex: none; height: 28px; min-height: 0; padding-inline: var(--s2); font-size: var(--fs-xs); }
.linkbar .btn svg { width: 14px; height: 14px; }

.item-text {
  background: var(--sunk); border-radius: var(--r); padding: 14px 16px;
  font-size: var(--fs-base); position: relative;
}
.item-text pre.rs-text { padding: 0; background: none; border-radius: 0; font-family: var(--font-sans); font-size: var(--fs-base); }
.item-text pre.rs-text a, .rs-link-card { color: var(--brand-600); }
.rs-link-card {
  display: flex; flex-wrap: wrap; align-items: center; gap: 4px 12px;
  padding: 12px 14px; border: var(--border-w) solid var(--line); border-radius: var(--r);
  background: var(--card); text-decoration: none; min-width: 0;
}
.rs-link-card b { font-size: var(--fs-md); color: var(--ink); overflow-wrap: anywhere; }
.rs-link-card small { flex-basis: 100%; order: 2; color: var(--ink-3); font-size: var(--fs-xs); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rs-link-card .btn { margin-inline-start: auto; }
.item-text .lbl {
  font-size: var(--fs-xs); color: var(--ink-3); display: flex;
  justify-content: space-between; align-items: center; margin-block-end: 6px;
}
.item-text .lbl .btn { background: none; border: 0; height: 28px; }

.item-file {
  display: flex; gap: 14px; align-items: center;
  border: var(--border-w) solid var(--line); border-radius: var(--r);
  padding: 10px; background: var(--card);
}
.item-file .pv {
  width: 96px; height: 72px; border-radius: var(--r-sm); flex: none;
  object-fit: cover; background: var(--brand-100);
}
.item-file .pv.doc {
  display: grid; place-items: center; background: var(--sunk);
  border: var(--border-w) solid var(--line);
}
.item-file .pv.doc svg { width: 22px; height: 22px; stroke: var(--ink-2); stroke-width: 1.75; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.item-file .if-body { min-width: 0; flex: 1; }
/* single-line filename, middle ellipsis: the stem span ellipsizes, the
   extension span stays pinned; b[title] carries the full name */
.item-file b.if-name { font-size: var(--fs-base); font-weight: 600; display: flex; align-items: baseline; min-width: 0; }
.item-file b.if-name .if-stem { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.item-file b.if-name .if-ext { flex: none; white-space: nowrap; }
.item-file small { font-size: var(--fs-xs); color: var(--ink-3); display: block; margin-block-start: 2px; }
.item-file .a { margin-inline-start: auto; display: flex; gap: 6px; flex: none; }

/* ── Result media (inline result card + /r page, one structure):
   single image = full main view (≤60vh, never cropped; download +
   size-delta line BELOW the image); multiple images = grid (phone 2
   cols / desktop 3) with click-to-zoom cells. ── */
.rs-media { display: flex; flex-direction: column; gap: var(--s2); min-width: 0; }
.rs-image { margin: 0; background: var(--sunk); text-align: center; border-radius: var(--r); overflow: hidden; }
.rs-image img {
  display: block; margin-inline: auto;
  max-width: 100%; max-height: 60vh; height: auto; width: auto;
  object-fit: contain;
}
/* size-delta + name + download under the media — small text only,
   never larger than body copy, never inside the card title */
.rs-img-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2); min-width: 0; }
.rs-img-meta small { font-size: var(--fs-xs); color: var(--ink-3); }
.rs-img-meta .rs-dl { margin-inline-start: auto; flex: none; }
.rs-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--s2); }
.rs-cell {
  margin: 0; display: flex; flex-direction: column; gap: var(--s1); min-width: 0;
  border: var(--border-w) solid var(--line); border-radius: var(--r-sm);
  padding: var(--s1); background: var(--card);
}
.rs-cell-img {
  display: block; width: 100%; padding: 0; border: 0; min-height: 0;
  border-radius: var(--r-xs); background: var(--sunk); cursor: zoom-in; overflow: hidden;
}
.rs-cell-img img {
  display: block; width: 100%; aspect-ratio: 4 / 3; object-fit: cover;
}
.rs-cell figcaption { min-width: 0; }
.rs-cell figcaption small { font-size: var(--fs-xs); color: var(--ink-3); }
.rs-cell figcaption .if-name { display: flex; min-width: 0; font-size: var(--fs-xs); font-weight: 600; color: var(--ink-2); }
.rs-cell figcaption .if-stem { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rs-cell figcaption .if-ext { flex: none; }
.rs-cell .rs-dl { align-self: flex-start; }
@media (max-width: 767px) {
  .rs-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Full-size lightbox (shared authority: common.js wireImageZoom) */
.img-zoom {
  position: fixed; inset: 0; z-index: var(--z-modal);
  display: grid; place-items: center; padding: var(--s4);
  background: var(--overlay); cursor: zoom-out;
}
.img-zoom.hidden { display: none; }
.img-zoom img {
  max-width: 92vw; max-height: 92vh; width: auto; height: auto;
  object-fit: contain; border-radius: var(--r-sm);
}

/* json item: collapsible code block (structure unchanged) */
.rs-json-details { border: var(--border-w) solid var(--line); border-radius: var(--r); overflow: hidden; }
pre.rs-text, pre.rs-json {
  font-family: var(--font-mono); font-size: var(--fs-sm); line-height: var(--lh-loose);
  white-space: pre-wrap; word-break: break-word; width: auto;
  background: var(--sunk); border-radius: var(--r-sm);
  padding: var(--s3); max-height: 380px; overflow: auto; margin: 0;
}
.rs-item.rs-json { white-space: normal; font-family: var(--font-sans); }
.rs-json-details summary {
  list-style: none; cursor: pointer; padding: var(--s2) var(--s3);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink-3);
}
.rs-json-details summary::-webkit-details-marker { display: none; }
.rs-json-details summary::before { content: "▸ "; }
[dir="rtl"] .rs-json-details summary::before { content: "◂ "; }
.rs-json-details[open] summary::before { content: "▾ "; }
.rs-json-details .rs-body { padding: var(--s3); }
.rs-json-head { border: 0; padding: var(--s1) var(--s2); }
.rs-item { border-radius: var(--r); }

/* legacy /f preview + /r SSR rows (pages keep their markup until the
   next batch; minimal styles so nothing collapses) */
.rs-item-head {
  display: flex; align-items: center; justify-content: space-between; gap: var(--s2);
  padding: var(--s2) var(--s3);
}
.rs-item-kind {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.05em;
  text-transform: uppercase; color: var(--ink-3);
}

@media (max-width: 767px) {
  .item-file { flex-wrap: wrap; }
  .item-file .a { margin-inline-start: 0; width: 100%; }
  .item-file .a .btn { flex: 1; }
  .item-file .pv { width: 72px; height: 56px; }
}

/* ── Tags & badges ─────────────────────────────────────────── */
.tag {
  display: inline-flex; align-items: center; gap: var(--s1);
  height: 22px; padding-inline: var(--s2);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.02em;
  background: var(--gray-100); color: var(--ink-2);
  border-radius: var(--r-xs);
}
.tag-brand { background: var(--brand-soft); color: var(--brand-deep); }
.tag-success { background: var(--ok-50); color: var(--ok); }
.tag-warning { background: var(--warn-50); color: var(--warn); }
.tag-danger { background: var(--danger-50); color: var(--danger); }
.tag-neutral { background: var(--gray-200); color: var(--gray-700); }
/* tool-card price/free variants (single .tag family) */
.tag.free { background: var(--ok-50); color: var(--ok-700); }
.tag.cost { background: var(--brand-50); color: var(--brand-600); }

/* ── Verified badge (membership mark; colors baked into the icon) ── */
.verified { display: inline-flex; width: 14px; height: 14px; vertical-align: -2px; flex: none; }
.verified svg { width: 100%; height: 100%; display: block; }
.user-menu { position: relative; display: flex; align-items: center; }
/* 语言入口 = 顶栏唯一挂载点: 菜单锚定到按钮自身 (所有视口可见),
   右对齐且永不超出视口 (RTL 由 518.css 镜像规则翻转)。 */
.lang-switch { position: relative; display: flex; align-items: center; }
.av-verified {
  position: absolute; inset-block-end: -3px; inset-inline-start: 20px;
  width: 15px; height: 15px; z-index: 1;
  box-shadow: 0 0 0 2px var(--bg); border-radius: 50%;
}

/* ── Code block (mono well) ────────────────────────────────── */
.code-block, .doc-pre, .agents-pre {
  background: var(--sunk); border: var(--border-w) solid var(--line);
  border-radius: var(--r-sm); padding: var(--s2) var(--s3);
  overflow-x: auto; font-family: var(--font-mono);
  font-size: var(--fs-xs); line-height: 1.6;
}
.code-block code, .doc-pre code, .agents-pre code { font-family: inherit; }

/* ── Hint / empty / note ───────────────────────────────────── */
.hint {
  display: flex; gap: var(--s2); align-items: flex-start;
  font-size: var(--fs-sm); color: var(--ink-2); line-height: var(--lh-base);
}
.hint svg { width: 15px; height: 15px; flex-shrink: 0; stroke: currentColor; stroke-width: 1.75; fill: none; margin-block-start: 2px; }
.empty {
  display: flex; flex-direction: column; align-items: center; gap: var(--s2);
  padding: var(--s8) var(--s4); text-align: center; color: var(--ink-2);
  font-size: var(--fs-base);
}
.empty svg { width: 36px; height: 36px; stroke: var(--gray-400); stroke-width: 1.5; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.empty .empty-title { font-size: var(--fs-md); font-weight: 700; color: var(--ink); }
.empty .empty-sub { font-size: var(--fs-sm); max-width: 44ch; }
.empty .empty-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--s2); }
.empty .empty-actions > * { margin: 0; }
.error-note {
  padding: var(--s3); border-radius: var(--r-sm);
  background: var(--danger-50); color: var(--danger-strong);
  font-size: var(--fs-base); font-weight: 600;
}

/* ── Table ─────────────────────────────────────────────────── */
.tbl { width: 100%; border-collapse: collapse; font-size: var(--fs-base); }
.tbl th {
  text-align: start; font-size: var(--fs-xs); font-weight: 700;
  letter-spacing: 0.04em; text-transform: uppercase; color: var(--ink-3);
  padding: var(--s2) var(--s3); border-block-end: var(--border-w) solid var(--line-2);
}
.tbl td { padding: var(--s3); border-block-end: var(--border-w) solid var(--line); vertical-align: middle; }
.tbl tr:last-child td { border-block-end: 0; }

/* ── Page head (title block above page content) ────────────── */
.page-head { display: flex; flex-direction: column; gap: var(--s2); margin-block-end: var(--s5); }
.page-head h1 { font-size: var(--fs-xl); font-weight: 750; line-height: var(--lh-tight); }
.page-head .page-head-sub { color: var(--ink-2); font-size: var(--fs-base); line-height: var(--lh-base); max-width: 60ch; }
.page-head .page-head-meta {
  display: flex; flex-wrap: wrap; align-items: center; gap: var(--s2) var(--s4);
  font-size: var(--fs-sm); color: var(--ink-2);
}
.page-head .page-head-meta .meta-item { display: inline-flex; align-items: center; gap: var(--s1); }
.page-head .page-head-meta svg { width: 15px; height: 15px; stroke: currentColor; stroke-width: 1.75; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.facts { display: flex; flex-direction: column; gap: var(--s1); font-size: var(--fs-sm); color: var(--ink-2); }
.facts .fact { display: flex; gap: var(--s2); align-items: baseline; }
.facts .fact svg { width: 14px; height: 14px; stroke: currentColor; stroke-width: 1.75; fill: none; align-self: center; flex-shrink: 0; }
.facts .fact b { color: var(--ink); font-weight: 650; }

/* ── Breadcrumb / back ─────────────────────────────────────── */
.crumbs { display: flex; align-items: center; gap: var(--s2); font-size: var(--fs-sm); color: var(--ink-2); margin-block-end: var(--s4); }
.crumbs a { color: var(--ink-2); display: inline-flex; align-items: center; gap: var(--s1); }
.crumbs a:hover { color: var(--brand); }
.crumbs .crumb-sep { color: var(--gray-400); }
.crumbs svg { width: 14px; height: 14px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; }

/* ── Modal ─────────────────────────────────────────────────── */
.modal {
  position: fixed; inset: 0; background: var(--overlay);
  -webkit-backdrop-filter: blur(2px); backdrop-filter: blur(2px);
  z-index: var(--z-modal); display: flex; align-items: center; justify-content: center;
  padding: var(--s4);
}
.modal.hidden { display: none; }
.modal-panel {
  width: min(420px, 100%); background: var(--bg);
  border: var(--border-w) solid var(--line); border-radius: var(--r-lg);
  padding: var(--s5) var(--s4) var(--s4); position: relative; box-shadow: var(--sh-4);
}
.modal-close {
  position: absolute; inset-block-start: var(--s2); inset-inline-end: var(--s2);
  background: none; border: 0; cursor: pointer; color: var(--ink-2);
  padding: var(--s2); border-radius: var(--r-sm); display: flex;
}
.modal-close svg { width: 16px; height: 16px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; }
@media (hover:hover) and (pointer:fine) { .modal-close:hover { background: var(--gray-100); color: var(--ink); } }

/* ── Toast ─────────────────────────────────────────────────── */
.toast {
  position: fixed; inset-block-end: var(--s5); inset-inline: 0;
  margin-inline: auto; width: fit-content; max-width: min(420px, calc(100% - var(--s6)));
  display: flex; align-items: center; gap: var(--s3);
  background: var(--gray-900); color: var(--brand-ink); border-radius: var(--r);
  padding: var(--s3) var(--s4); font-size: var(--fs-base); font-weight: 600;
  box-shadow: var(--sh-3); z-index: var(--z-toast);
}
.toast svg { width: 17px; height: 17px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; stroke-linejoin: round; flex-shrink: 0; }
.toast-success svg { color: var(--ok); }
.toast-error svg { color: var(--danger); }

/* ── Chips (format tokens etc.) ────────────────────────────── */
.chip-row { display: inline-flex; flex-wrap: wrap; gap: var(--s1); }
.chip {
  display: inline-flex; align-items: center; height: 22px; padding-inline: var(--s2);
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: 0.03em;
  background: var(--gray-100); color: var(--ink-2); border-radius: var(--r-xs);
}

/* ── Copy field (value + copy button, e.g. MCP name) ───────── */
.copyfield { display: flex; gap: var(--s2); align-items: stretch; }
.copyfield .input { font-family: var(--font-mono); }
/* 桌面紧凑字号; ≤767 回落底部输入地板 16px (防聚焦放大) */
@media (min-width: 768px) { .copyfield .input { font-size: var(--fs-sm); } }

/* ── Tool search (market + home tools section — one component) ── */
.tool-search { position: relative; width: 100%; }
.tool-search > svg { position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 18px; height: 18px; stroke: var(--ink-2); fill: none; pointer-events: none; }
.tool-search input { width: 100%; box-sizing: border-box; padding: 10px 14px 10px 38px; border: 1px solid var(--line-2); border-radius: var(--r-full); background: var(--bg); color: var(--ink); }
.tool-search input:focus { outline: 2px solid var(--brand); outline-offset: -1px; }

/* ── Tool card (.tc — ONE card: home bento + market + author page +
   favorites; interior markup single-sourced in
   partials/tool_identity.html tool_card). Four fixed rows: icon+name /
   description (fixed 2-line clamp) / bottom tag row pinned to the card
   bottom — grid rows stretch, so same-row cards are equal height. ── */
.tc {
  position: relative; display: flex; flex-direction: column; min-width: 0;
  background: var(--card); border: var(--border-w) solid var(--line);
  border-radius: var(--r-lg); padding: var(--s4); box-shadow: var(--sh-1);
  color: var(--ink); text-decoration: none;
  transition: box-shadow var(--ease), border-color var(--ease), transform var(--ease-in);
}
@media (hover:hover) and (pointer:fine) {
  .tc:hover { box-shadow: var(--sh-2); transform: translateY(-2px); border-color: var(--line-2); }
}
.tc-h { display: flex; align-items: center; gap: 10px; min-width: 0; }
.tc .ic {
  width: 40px; height: 40px; border-radius: 12px; flex: none;
  display: grid; place-items: center; background: var(--sunk); color: var(--ink);
}
.tc .ic svg { width: 20px; height: 20px; stroke: currentColor; stroke-width: 1.75; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.tc-h h4 {
  margin: 0; font-size: var(--fs-md); font-weight: 650; letter-spacing: -0.01em;
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.tc-desc {
  margin: 8px 0 0; font-size: 13px; color: var(--ink-2); line-height: var(--lh-base);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  min-height: calc(2 * var(--lh-base) * 1em);
}
.tc .ft2 {
  margin-top: auto; padding-top: 12px; min-width: 0;
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: 12px; color: var(--ink-3);
}
/* 标签从不截断: 窄卡上整枚标签换到下一行, 同行卡片仍由网格拉伸等高 */
.tc .ft2 .tag { flex: 0 0 auto; white-space: nowrap; }
.tc .by {
  margin-inline-start: auto; flex: 0 1 auto; min-width: 0;
  display: flex; align-items: center; gap: 3px;
  font-size: 12px; color: var(--ink-3); white-space: nowrap;
}
.tc .by .by-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.tc .fav-mcp {
  flex: 1; min-width: 0; margin-inline-start: auto;
  font-family: var(--font-mono); font-size: 12px; color: var(--ink-3);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
@media (max-width: 767px) {
  .tc { padding: 14px; }
  .tc-desc { font-size: 12px; }
  .tc .ic { width: 34px; height: 34px; border-radius: 10px; }
}

/* ── Tool input — the composer (shared component: home + tool page).
   Structure lives in pages/tool-input.js; DOM per the v2 prototype:
   .composer > .c-err + .c-files > .chipf + .c-text + .params >
   .prow (label + .seg/.input/.switch) + .c-bar (.ib clip + .opt
   delivery pill + .sp + .send). Legacy hooks kept for tests/JS:
   .ti-file-input (hidden file input), .ti-run (submit), .ti-error,
   .ti-progress. ──────────────────────────────────────────────── */
.composer {
  background: var(--card); border: var(--border-w) solid var(--line-2);
  border-radius: var(--r-xl); box-shadow: var(--sh-3);
  text-align: start; overflow: visible; position: relative;
  transition: border-color var(--ease), box-shadow var(--ease);
}
.composer.focus { border-color: rgba(255, 77, 77, 0.5); box-shadow: 0 0 0 4px rgba(255, 77, 77, 0.10), var(--sh-3); }
.composer.dragover { border-color: var(--brand); border-style: dashed; }
.composer .c-err { margin: var(--s3) var(--s4) 0; }
.c-files { display: flex; gap: var(--s2); flex-wrap: wrap; padding: 14px 16px 0; }
.c-files:empty { display: none; }
/* 空态上传区: 整块点击/拖入 (files_max>0 才渲染) */
.ti-drop {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; margin: 14px 16px 0; min-height: 132px; padding: var(--s3);
  width: calc(100% - 32px); box-sizing: border-box;
  border: 1.5px dashed var(--line-2); border-radius: var(--r-lg);
  background: none; font: inherit; cursor: pointer; text-align: center;
}
.ti-drop[hidden] { display: none; }
.ti-drop .dz-ic svg { width: 26px; height: 26px; stroke: var(--ink-3); stroke-width: 1.6; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.ti-drop b { font-size: var(--fs-md); font-weight: 650; color: var(--ink); }
.ti-drop small { font-size: var(--fs-xs); color: var(--ink-3); }
@media (hover:hover) and (pointer:fine) { .ti-drop:hover { border-color: var(--brand); background: var(--brand-50); } }
.ti-drop:focus-visible, .ti-drop.dragover { border-color: var(--brand); background: var(--brand-50); outline: none; }
/* 24h 额度低余量提示 (上传区下方一行; 数据 = limits 投影 dailyRemaining) */
.ti-quota { margin: 8px 16px 0; font-size: var(--fs-xs); color: var(--warn); }
.chipf {
  display: flex; align-items: center; gap: 10px; padding: 6px 8px 6px 6px;
  border: var(--border-w) solid var(--line); border-radius: 12px;
  background: var(--sunk); font-size: 13px; max-width: 260px;
}
.chipf .th { width: 36px; height: 36px; border-radius: 8px; flex: none; object-fit: cover; background: var(--brand-100); }
.chipf .th.d { background: var(--card); border: var(--border-w) solid var(--line); display: grid; place-items: center; }
.chipf .th.d svg { width: 17px; height: 17px; stroke: var(--ink-2); stroke-width: 1.75; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.chipf b { font-weight: 600; display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 160px; }
.chipf small { color: var(--ink-3); font-size: var(--fs-xs); display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 160px; }
.chipf .x {
  color: var(--ink-3); margin-left: 2px; background: none; border: 0;
  cursor: pointer; display: grid; place-items: center; padding: var(--s1);
  border-radius: var(--r-xs);
}
.chipf .x svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2; fill: none; stroke-linecap: round; }
@media (hover:hover) and (pointer:fine) { .chipf .x:hover { color: var(--danger); background: var(--danger-50); } }

.c-text {
  display: block; width: 100%; padding: 16px 20px 8px; min-height: 92px;
  font: inherit; font-size: 16px; line-height: var(--lh-base); color: var(--ink);
  background: none; border: 0; outline: none; resize: vertical;
}
.c-text::placeholder { color: var(--ink-3); }
.c-text-hint { padding: 16px 20px 8px; min-height: 60px; font-size: 16px; color: var(--ink-3); }

/* 纯文本工具 (files_max=0) 的对话框形态: 单个自动增高输入框
   (1..8 行, 封顶内部滚动), 发送按钮在输入框右下角内侧。 */
.ti-chat-wrap { position: relative; margin: 14px 16px 0; }
.ti-chat-wrap .c-text {
  padding: 12px 60px 12px 16px; min-height: 48px;
  max-height: calc(8 * 1.55em + 24px);
  resize: none; overflow-y: auto;
  background: var(--sunk); border-radius: var(--r-lg);
  transition: box-shadow var(--ease);
}
.ti-chat-wrap .c-text:focus { box-shadow: 0 0 0 3px var(--brand-100); }
.ti-chat-wrap .send {
  position: absolute; inset-block-end: 8px; inset-inline-end: 8px;
  width: 36px; height: 36px;
}
.ti-chat-wrap .send svg { width: 16px; height: 16px; }

/* 行尾"+ 添加"小块: 已有文件且未达上限时出现在文件列表末尾
   (chipf 底形 + 虚线描边区分真实文件行) */
.ti-add-block {
  border: 1.5px dashed var(--line-2); background: none;
  color: var(--ink-2); font: inherit; font-size: 13px; font-weight: 550;
}
.ti-add-block .th.d { background: var(--brand-50); }
.ti-add-block b { color: var(--brand); }
@media (hover:hover) and (pointer:fine) { .ti-add-block:hover { border-color: var(--brand); color: var(--ink); } }
.ti-add-block:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }

.params { display: flex; flex-direction: column; gap: 14px; padding: 4px 20px 6px; }
.params:empty { display: none; }
.params .divider { height: 1px; background: var(--line); margin: 4px 0 0; }
/* 参数行: 桌面 = 标签在左、控件在右; 手机 = 标签在上、控件占满宽度
   (首页与工具页同一套 — 首页 hero 与 .toolpage 共用本组件) */
.prow { display: flex; align-items: center; gap: var(--s2) var(--s3); }
.prow > label, .prow > .prow-label {
  font-size: 13px; color: var(--ink-3);
  flex: 0 0 auto; min-width: 56px; max-width: 44%;
  overflow-wrap: anywhere;
}
/* 控件自适应宽度 (不再写死 180px): 输入框按内容伸缩, seg 随选项换行 */
.prow .input { width: auto; min-width: 96px; max-width: 240px; flex: 0 1 auto; }
.prow .seg, .prow .switch { flex: 0 1 auto; max-width: 100%; }
.prow-text { align-items: flex-start; }
.prow-text > .prow-label { padding-top: 8px; }
.prow-text > .textarea { flex: 1; min-width: 220px; }
@media (max-width: 767px) {
  .prow { flex-direction: column; align-items: stretch; gap: var(--s1); }
  .prow > .prow-label { min-width: 0; max-width: none; padding-top: 0; }
  .prow .input { width: 100%; max-width: none; }
  .prow-text > .textarea { min-width: 0; width: 100%; }
}
/* 参数分段选项: 超出一行自动换行; 外框普通圆角 (换行后不再是胶囊形) */
.seg { display: inline-flex; padding: 3px; background: var(--sunk); border-radius: var(--r-full); gap: 2px; flex-wrap: wrap; }
.tp-seg { border-radius: var(--r-sm); }
.seg button {
  height: 30px; padding: 0 13px; border-radius: var(--r-full); border: 0;
  background: none; display: inline-flex; align-items: center;
  font: inherit; font-size: 13px; font-weight: 550; color: var(--ink-2); cursor: pointer;
}
.seg button.on { background: var(--card); color: var(--ink); box-shadow: var(--sh-1); }

/* 参数卡片: 参数区每行 = 标签在上、控件在下 (各宽度一致); 枚举参数的
   每个选项是一张独立卡片, 网格自动换行, 选中 = 品牌色描边。开关行保持
   标签与开关同一行。比例值 (W:H) 的选项卡内画出该比例的小框。 */
.params .prow { flex-direction: column; align-items: stretch; gap: var(--s2); }
.params .prow > .prow-label {
  min-width: 0; max-width: none; padding-top: 0;
  font-size: 13px; font-weight: 600; color: var(--ink-2);
}
.params .prow.prow-bool { flex-direction: row; align-items: center; justify-content: space-between; }
.params .prow-text > .textarea { min-width: 0; width: 100%; }
.params .prow .tp-seg {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(84px, 100%), 1fr));
  gap: 8px; width: 100%; padding: 0; background: none; border-radius: 0;
}
.tp-seg .tp-option {
  height: auto; min-height: 40px; min-width: 0; padding: 8px 10px; gap: 6px;
  flex-direction: column; overflow-wrap: anywhere; justify-content: center; text-align: center;
  border: 1px solid var(--line-2); border-radius: var(--r-sm);
  background: var(--card); color: var(--ink-2); box-shadow: none;
  transition: border-color .15s, color .15s, background .15s;
}
.tp-seg .tp-option.on {
  border-color: var(--brand); color: var(--brand); background: var(--brand-50);
  box-shadow: inset 0 0 0 1px var(--brand);
}
@media (hover:hover) and (pointer:fine) {
  .tp-seg .tp-option:hover:not(.on) { border-color: var(--ink-4); color: var(--ink); }
}
.tp-seg .tp-option:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.tp-seg .tp-ratio {
  display: block; height: 22px; max-width: 36px;
  border: 1.5px solid currentColor; border-radius: 3px; opacity: .8;
}
.tp-seg .tp-ratio.free { aspect-ratio: 1; border-style: dashed; }

/* "更多参数"折叠: 参数超过 3 个时, 其余收进展开区 */
.ti-more { display: flex; flex-direction: column; gap: 14px; }
.ti-more-btn {
  align-self: flex-start; display: inline-flex; align-items: center; gap: 6px;
  min-height: 0; padding: 2px 0; border: 0; border-radius: 0;
  background: none; color: var(--ink-3);
  font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
}
.ti-more-btn .chev {
  width: 7px; height: 7px; flex: none;
  border-inline-end: 1.5px solid currentColor; border-block-end: 1.5px solid currentColor;
  transform: rotate(-45deg); transition: transform var(--ease);
}
.ti-more-btn.open .chev { transform: rotate(135deg); }
.ti-more-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.ti-more-body { display: flex; flex-direction: column; gap: 14px; }
.ti-more-body[hidden] { display: none; }

.c-bar { display: flex; align-items: center; gap: 6px; padding: 10px 12px 12px; flex-wrap: wrap; position: relative; }
.c-bar .sp { flex: 1; }
.ib {
  width: 36px; height: 36px; border-radius: var(--r-full); border: 0;
  display: grid; place-items: center; color: var(--ink-2); background: none; cursor: pointer;
}
.ib svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; }
@media (hover:hover) and (pointer:fine) { .ib:hover { background: rgba(11, 13, 16, 0.05); } }
@media (max-width: 767px) { .ib { position: relative; } .ib::after { content: ""; position: absolute; inset: -5px; } }
.opt {
  display: inline-flex; align-items: center; gap: 6px; height: 36px; padding: 0 12px;
  border-radius: var(--r-full); background: var(--sunk); border: 0;
  font: inherit; font-size: 13px; color: var(--ink-2); font-weight: 500; cursor: pointer;
}
.opt b { color: var(--ink); font-weight: 600; }
.opt svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.send {
  width: 40px; height: 40px; border-radius: 50%; background: var(--brand);
  color: var(--brand-ink); border: 0; display: grid; place-items: center;
  cursor: pointer; box-shadow: 0 6px 16px -6px rgba(255, 77, 77, 0.7);
}
.send svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 2.2; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.send.wide { width: auto; padding: 0 18px; border-radius: var(--r-full); gap: 6px; display: inline-flex; align-items: center; font: inherit; font-weight: 650; font-size: var(--fs-base); }
.send:disabled { opacity: 0.55; cursor: default; pointer-events: none; }
.ti-progress { font-size: var(--fs-sm); color: var(--ink-3); font-variant-numeric: tabular-nums; }

/* delivery pill popover (existing values, existing entitlement logic) */
.c-del-pop {
  position: absolute; inset-block-end: calc(100% + 8px); inset-inline-end: 0;
  z-index: var(--z-dropdown); background: var(--card);
  border: var(--border-w) solid var(--line-2); border-radius: var(--r);
  box-shadow: var(--sh-3); padding: var(--s4); display: flex; gap: var(--s4);
  min-width: 260px;
}
.c-del-pop .field { min-width: 110px; }

@media (max-width: 767px) {
  .composer { border-radius: 22px; }
  .c-text { min-height: 72px; }
  .c-bar { gap: 4px; }
  /* 两行底栏: 第一行工具选择器占满 (首页); 第二行 有效期 + 运行 —
     运行靠右且与有效期同一行 (任何宽度都不单独换行): .sp 退场,
     运行吃 margin-inline-start:auto, 进度文本可收缩。 */
  .c-bar .tsel { flex: 1 1 100%; }
  .c-bar .sp { display: none; }
  .c-bar .ti-run { margin-inline-start: auto; }
  .ti-progress { flex-shrink: 1; min-width: 0; overflow: hidden; white-space: nowrap; }
  .send.wide { padding: 0 14px; min-height: 44px; }
  /* 添加文件: 移动端图标按钮; .ib 统一伪元素扩点击区到 ≥44 (视觉不变) */
  .tp-seg .tp-option { min-height: 44px; }
}
/* 输入区挂载预留高度 (CLS) */
.ti-mount { min-height: 224px; }

/* Phone: file rows wrap — name keeps its line, meta + actions flow */
@media (max-width: 599px) {
  .file-row { flex-wrap: wrap; }
  .file-row .file-name { flex-basis: calc(100% - 52px); }
  .file-row .btn { margin-inline-start: auto; }
}
/* Mixed-direction meta strings (Arabic labels + Latin digits) */
.file-meta { unicode-bidi: plaintext; }

/* Phone: result actions collapse to icon buttons (labels via
   aria-label + title on every button) */
@media (max-width: 599px) {
  .r-actions .btn span { display: none; }
  .r-actions .btn { width: 44px; padding: 0; }
}

/* ── Auth modal (login/register overlay, site-wide) ────────────
   Rides the .modal/.modal-panel primitives; panel takes the v2
   radius/shadow, forms reuse .field/.input/.btn. ── */
.auth-modal { width: min(400px, 100%); border-radius: var(--r-xl); box-shadow: var(--sh-3); padding: var(--s5) var(--s4) var(--s4); }
.auth-modal h2 { font-size: var(--fs-lg); font-weight: 750; text-align: center; margin: 0 0 var(--s3); }
.auth-modal .auth-x-wrap .x-login { width: 100%; }
.auth-modal .seg { width: 100%; margin: 0 0 var(--s3); }
.auth-modal .seg button { flex: 1; }
.auth-modal .auth-sub { text-align: center; font-size: var(--fs-sm); color: var(--ink-3); margin: -6px 0 var(--s3); }
.auth-modal form { display: flex; flex-direction: column; gap: var(--form-gap); }
.auth-modal .auth-terms { text-align: center; font-size: var(--fs-xs); color: var(--ink-3); margin: var(--s3) 0 0; }
.auth-modal .auth-terms a { color: var(--ink-2); text-decoration: underline; }
@media (max-width: 767px) { .auth-modal { padding: var(--s4) var(--s3); } }

/* ── Auth full pages (v2 narrow centered card) ──────────────── */
.auth-card { background: var(--card); border: 1px solid var(--line); border-radius: var(--r-xl); box-shadow: var(--sh-3); padding: var(--s6) var(--s5); display: flex; flex-direction: column; gap: var(--s4); }
.auth-card h1 { font-size: var(--fs-xl); text-align: center; margin: 0; }
.auth-card .auth-sub { text-align: center; font-size: var(--fs-sm); color: var(--ink-3); margin: -10px 0 0; }
.auth-card .auth-terms { text-align: center; font-size: var(--fs-xs); color: var(--ink-3); margin: 0; }
.auth-card .auth-terms a { color: var(--ink-2); text-decoration: underline; }
@media (max-width: 767px) { .auth-card { padding: var(--s5) var(--s4); } }

/* ── Mobile input floor (site-wide, phone widths) ──────────────
   iOS/Android auto-zoom any focused control rendered below 16px.
   On ≤767px every input-like control is forced to 16px; the compact
   desktop sizes live in min-width:768px blocks next to their page
   rules (518.css/samelabs.css), never in !important fights. This
   file loads last, so the class selectors here outrank the base
   .input/.select/.sl-input sizes above. */
@media (max-width: 767px) {
  input, select, textarea,
  .input, .textarea, .select, .sl-input { font-size: 16px; }
}

/* 分享条 (partials/share_bar.html): 复制链接 / 系统分享 / X / 二维码 —
   等宽图标卡片一行排开, 图标在上、短标签在下; /f /r 工具页 作者页同一组件 */
.share-bar { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 8px; }
.share-bar .sb-btn {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  min-height: 56px; min-width: 0; padding: 8px 4px;
  border: 1px solid var(--line-2); border-radius: var(--r-sm); background: var(--card);
  font: inherit; font-size: 12px; font-weight: 550; color: var(--ink-2);
  text-decoration: none; cursor: pointer; transition: border-color .15s, color .15s;
}
.share-bar .sb-btn > span:last-child { max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.share-bar .sb-btn svg { width: 18px; height: 18px; stroke: currentColor; stroke-width: 1.8; fill: none; stroke-linecap: round; stroke-linejoin: round; }
.share-bar .sb-btn .x-glyph { font-size: 17px; height: 18px; display: inline-flex; align-items: center; }
@media (hover:hover) and (pointer:fine) { .share-bar .sb-btn:hover { border-color: var(--ink-4); color: var(--ink); } }
.share-bar .sb-btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.share-bar.sb-compact { display: inline-flex; gap: 6px; vertical-align: middle; }
.share-bar.sb-compact .sb-btn { flex-direction: row; min-height: 30px; width: 30px; padding: 0; border-radius: var(--r-full); }
.share-bar.sb-compact .sb-btn svg { width: 15px; height: 15px; }
.share-bar.sb-compact .sb-btn .x-glyph { font-size: 14px; height: 15px; }
.share-bar.sb-compact .sb-btn > span:last-child:not(.x-glyph) { display: none; }
