/* =========================================================================
   JSON Editor Pro — styles
   Dark theme is default; light theme via [data-theme="light"] on <html>.
   ========================================================================= */

:root,
[data-theme="dark"] {
  /* Palette tuned to match Monaco's `vs-dark` theme — neutral dark grays
     instead of dark blue, so the surrounding UI flows continuously into the
     editor surface (no jarring color seam between chrome and code). */
  --bg: #181818;
  --bg-grad: radial-gradient(circle at top right, #232323 0%, #1c1c1c 45%, #141414 100%);
  --panel: #1f1f1f;
  --panel-alt: #252526;
  --panel-deep: #1a1a1a;
  --text: #cccccc;
  --text-strong: #ffffff;
  --muted: #858585;
  --line: #2d2d2d;
  --line-soft: #232323;
  --primary: #0078d4;
  --primary-hover: #1f8ee0;
  --primary-soft: rgba(0, 120, 212, 0.22);
  --success: #4ec9b0;
  --error: #f48771;
  --warning: #d7ba7d;
  --shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
  --pane-bg: #1e1e1e;
  --pane-header-bg: #252526;
  --code-bg: #1e1e1e;
  --tree-bg: #1e1e1e;
  --splitter-bg: #252526;
  --splitter-handle: #3c3c3c;
  --button-bg: #2a2d2e;
  --button-text: #cccccc;
  --button-hover: #37373d;
  --search-bg: #1e1e1e;
  --tooltip-bg: #2d2d30;
  /* Editor / code font — system monospace stack (no external font CDN) */
  --mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace;
  color-scheme: dark;
}

[data-theme="light"] {
  --bg: #f8fafc;
  --bg-grad: radial-gradient(circle at top right, #eef2f7 0%, #f8fafc 45%, #f0f4f9 100%);
  --panel: #ffffff;
  --panel-alt: #f1f5fb;
  --panel-deep: #ffffff;
  --text: #1c2433;
  --text-strong: #0d1424;
  --muted: #5e6c85;
  --line: #d8def0;
  --line-soft: #e6ebf8;
  --primary: #2f6df5;
  --primary-hover: #1a55d6;
  --primary-soft: rgba(47, 109, 245, 0.12);
  --success: #18915b;
  --error: #d23f33;
  --warning: #c98800;
  --shadow: 0 6px 24px rgba(28, 36, 51, 0.08);
  --pane-bg: #ffffff;
  --pane-header-bg: var(--panel-alt);
  --code-bg: #ffffff;
  --tree-bg: #ffffff;
  --splitter-bg: #e2e7f3;
  --splitter-handle: #b0bcd6;
  --button-bg: #eef2fa;
  --button-text: #1c2433;
  --button-hover: #e0e7f5;
  --search-bg: #f4f7fd;
  --tooltip-bg: #ffffff;
  color-scheme: light;
}

* {
  box-sizing: border-box;
}

/* Ensure [hidden] always wins over any display property set in author styles. */
[hidden] { display: none !important; }

html, body {
  height: 100%;
}

body {
  margin: 0;
  min-height: 100vh;
  font-family: Inter, "Segoe UI", system-ui, -apple-system, sans-serif;
  background: var(--bg-grad);
  color: var(--text);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  overscroll-behavior: none;
}

button {
  font-family: inherit;
}

/* =========================================================================
   Icons (Lucide-style inline SVG).
   All icons inherit color via `currentColor` so they pick up theme + state
   (hover, active, disabled) automatically from the parent element.
   The SVG fills its container — wrap it in a sized element (e.g. .side-btn-icon,
   .splitter-icon) to control the rendered size.
   ========================================================================= */
.lucide {
  width: 100%;
  height: 100%;
  display: block;
  /* `!important` here defends against any UA / library default that might
     otherwise paint the SVG black (browsers default to fill: black; stroke: none
     on <svg>, so without these the icons render as solid black silhouettes
     of nothing — i.e. invisible — instead of stroked outlines). */
  fill: none !important;
  stroke: currentColor !important;
  stroke-width: 1.75;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
  flex-shrink: 0;
  color: inherit;
}

/* Inherit currentColor through every nested SVG element. */
.lucide * {
  fill: none;
  stroke: currentColor;
  vector-effect: non-scaling-stroke;
}

/* =========================================================================
   App shell layout
   ========================================================================= */

/* Outer page grid: main app column + optional right ad rail (xml-editor, etc.) */
.page-grid {
  --ad-rail-width: clamp(160px, 10vw, 300px);
  width: 100%;
  margin: 0;
  padding: clamp(0.55rem, 1.1vw, 1rem);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: clamp(0.5rem, 0.9vw, 0.85rem);
  min-height: 100dvh;
  align-items: start;
  box-sizing: border-box;
}

.page-grid > .app-shell {
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 0;
  min-height: 0;
}

@media (min-width: 900px) {
  /* Match legacy single-column width until the right rail is active */
  .page-grid:not(.page-grid--rail-active) {
    width: 90%;
  }
}

@media (min-width: 1280px) {
  .page-grid.page-grid--rail-active {
    width: 100%;
    grid-template-columns: minmax(0, 1fr) var(--ad-rail-width);
  }
}

.app-shell {
  /* Narrow viewports: full bleed. ≥900px without page-grid: ~10% margin on the right. */
  width: 100%;
  margin: 0;
  padding: clamp(0.55rem, 1.1vw, 1rem);
  display: grid;
  /* Workspace row: viewport-relative min height so editors stay usable on all screens */
  grid-template-rows: auto minmax(clamp(280px, 52dvh, 920px), 1fr) auto auto auto;
  gap: clamp(0.5rem, 0.9vw, 0.85rem);
  min-height: 100dvh;
}

@media (min-width: 900px) {
  .app-shell {
    width: 90%;
  }

  .page-grid > .app-shell {
    width: 100%;
  }
}

/* =========================================================================
   Ad slots (hidden until AdSense / creative is wired)
   ========================================================================= */

.ad-slot {
  display: none;
  box-sizing: border-box;
  border: 1px solid var(--line);
  border-radius: 14px;
  background: var(--panel);
  box-shadow: var(--shadow);
  overflow: hidden;
}

.ad-slot:not([hidden]) {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.35rem;
  padding: 0.45rem 0.55rem 0.55rem;
}

.ad-slot__label {
  margin: 0;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  line-height: 1.2;
}

.ad-slot__inner {
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
}

.ad-slot--leaderboard:not([hidden]) {
  min-height: 90px;
}

.ad-slot--incontent:not([hidden]) {
  min-height: 0;
  margin: 0.15rem 0;
}

.how-to-grid > .ad-slot--incontent {
  grid-column: 1 / -1;
}

.ad-rail {
  display: none;
  position: sticky;
  top: clamp(0.55rem, 1.1vw, 1rem);
  align-self: start;
  max-height: calc(100dvh - 2 * clamp(0.55rem, 1.1vw, 1rem));
  overflow: hidden;
}

.ad-rail:not([hidden]) {
  display: flex;
  flex-direction: column;
  min-height: 600px;
}

.ad-rail .ad-slot__inner {
  flex: 1 1 auto;
  min-height: 250px;
}

.page-grid--rail-hidden .ad-rail:not([hidden]),
.ad-rail--off {
  display: none !important;
}

@media (max-width: 1279px) {
  .ad-rail:not([hidden]) {
    display: none !important;
  }

  .page-grid.page-grid--rail-active {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* =========================================================================
   Top bar
   ========================================================================= */

.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  padding: 0.7rem 1rem;
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 14px;
  box-shadow: var(--shadow);
  flex-wrap: wrap;
}

.brand {
  flex: 0 0 auto;
}

.eyebrow {
  margin: 0;
  color: var(--muted);
  font-size: 0.7rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}

h1 {
  margin: 0.15rem 0 0;
  font-size: clamp(1rem, 1.6vw, 1.25rem);
  color: var(--text-strong);
}

/* One-line feature summary under the title. Stays muted so it doesn't
   compete with the brand H1 for visual hierarchy, but readable enough
   to give first-time visitors an at-a-glance understanding of what the
   app does. clamp() keeps the size proportional on tablet sizes. */
.tagline {
  margin: 0.2rem 0 0;
  color: var(--text);
  font-size: clamp(0.78rem, 1.05vw, 0.86rem);
  line-height: 1.35;
  max-width: 60ch;
}

/* Privacy / "no-server" chip. Tinted with --primary so it reads as a
   trust signal rather than just decorative metadata. We use a soft
   background + 1px border so it sits visually halfway between the
   muted eyebrow text and a fully colored CTA — important enough to
   notice on first paint, not loud enough to outshine the H1. */
.privacy-chip {
  display: inline-flex;
  align-items: center;
  gap: 0.4rem;
  margin-top: 0.45rem;
  padding: 0.25rem 0.55rem;
  font-size: 0.72rem;
  font-weight: 500;
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--primary) 40%, var(--line) 60%);
  border-radius: 999px;
  white-space: nowrap;
  letter-spacing: 0.01em;
}

.privacy-chip .lucide {
  width: 12px;
  height: 12px;
  fill: none !important;
  stroke: currentColor !important;
  stroke-width: 2;
}

.privacy-chip-em {
  font-weight: 700;
  color: var(--text-strong, var(--text));
  letter-spacing: 0.02em;
}

.privacy-chip-sep {
  font-weight: 400;
  opacity: 0.65;
}

.topbar-tools {
  display: flex;
  align-items: center;
  gap: 0.65rem;
  flex-wrap: wrap;
}

.action-group {
  display: inline-flex;
  gap: 0.35rem;
}

/* Generic button */
.btn {
  border: 1px solid transparent;
  border-radius: 8px;
  padding: 0.5rem 0.75rem;
  font-size: 0.85rem;
  cursor: pointer;
  color: var(--button-text);
  background: var(--button-bg);
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease, transform 0.05s ease;
  white-space: nowrap;
}

.btn:hover {
  background: var(--button-hover);
}

.btn:active {
  transform: translateY(1px);
}

.btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

.btn-primary {
  background: var(--primary);
  color: #ffffff;
}

.btn-primary:hover {
  background: var(--primary-hover);
}

.btn-muted {
  background: var(--button-bg);
}

.theme-btn {
  width: 2.4rem;
  padding: 0.4rem 0;
  display: inline-grid;
  place-items: center;
  font-size: 0.95rem;
}

.theme-btn {
  color: var(--text);
}

.theme-btn .theme-icon-light,
.theme-btn .theme-icon-dark {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1rem;
  height: 1rem;
}

.theme-btn .theme-icon-light { display: none; }
[data-theme="light"] .theme-btn .theme-icon-light { display: inline-flex; }
[data-theme="light"] .theme-btn .theme-icon-dark { display: none; }

/* Search */
.search-box {
  display: inline-flex;
  align-items: center;
  background: var(--search-bg);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0.2rem 0.4rem;
  gap: 0.3rem;
  min-width: 220px;
}

.search-box:focus-within {
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}

.search-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 0.95rem;
  height: 0.95rem;
  color: var(--text);
  margin-left: 0.25rem;
  flex: 0 0 auto;
}

.search-input {
  border: 0;
  background: transparent;
  color: var(--text);
  outline: none;
  font-size: 0.85rem;
  flex: 1;
  min-width: 90px;
  padding: 0.35rem 0.2rem;
}

.search-input::placeholder {
  color: var(--muted);
}

.search-count {
  font-size: 0.72rem;
  color: var(--muted);
  font-variant-numeric: tabular-nums;
  padding: 0 0.2rem;
}

.search-nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border: 0;
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  padding: 0;
  border-radius: 6px;
  line-height: 1;
  flex: 0 0 auto;
}

.search-nav:hover {
  background: var(--button-hover);
  color: var(--text);
}

/* =========================================================================
   Workspace = sidebar + split shell
   ========================================================================= */

/* ── Workspace: toolbar on top, editors below ─────────────────────────── */
.workspace {
  display: flex;
  flex-direction: column;
  gap: clamp(0.5rem, 0.9vw, 0.85rem);
  min-height: 0;
  flex: 1 1 auto;
  height: 100%;
}

/* Sidebar — compact horizontal action bar */
.sidebar {
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 14px;
  padding: 0.3rem 0.5rem;
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  gap: 0.3rem;
  overflow-x: auto;
  scrollbar-width: none;
  box-shadow: var(--shadow);
  align-items: center;
}

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

.sidebar-group {
  display: flex;
  flex-direction: row;
  gap: 0.15rem;
  padding-bottom: 0;
  padding-right: 0.5rem;
  border-bottom: 0;
  border-right: 1px solid var(--line-soft);
  flex: 0 0 auto;
  align-items: center;
}

.sidebar-group:last-child {
  border-right: 0;
}

.sidebar-group-end {
  border-bottom: 0;
  border-right: 0;
  margin-top: 0;
  margin-left: auto;
}

/* Section labels hidden — button labels carry the context */
.sidebar-title {
  display: none;
}

.side-btn {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.38rem 0.6rem;
  border-radius: 8px;
  background: transparent;
  border: 1px solid transparent;
  color: var(--text);
  font-size: 0.82rem;
  cursor: pointer;
  text-align: left;
  width: auto;
  flex-shrink: 0;
  position: relative;
  transition: background 0.15s ease, border-color 0.15s ease;
}

.side-btn:hover {
  background: var(--button-bg);
  border-color: var(--line);
}

.side-btn.is-active {
  background: color-mix(in srgb, var(--primary) 12%, var(--panel-alt) 88%);
  border-color: var(--primary);
  color: var(--primary);
}

.side-btn.is-active .side-btn-icon {
  color: var(--primary);
}

.side-btn.is-disabled,
.side-btn:disabled {
  opacity: 0.55;
  cursor: not-allowed;
}

.side-btn.is-disabled:hover,
.side-btn:disabled:hover {
  background: transparent;
  border-color: transparent;
}

.side-btn-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.15rem;
  height: 1.15rem;
  color: var(--text);
  flex: 0 0 auto;
}

.side-btn:hover .side-btn-icon,
.side-btn:focus-visible .side-btn-icon {
  color: var(--primary);
}

.side-btn-label {
  flex: 1;
}

.badge-soon {
  font-size: 0.6rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  background: var(--primary-soft);
  color: var(--primary);
  padding: 0.1rem 0.35rem;
  border-radius: 999px;
}

.hidden-input {
  display: none;
}

/* =========================================================================
   Split shell (editor | splitter | tree)
   ========================================================================= */

.split-shell {
  display: grid;
  /* minmax(0, …) lets the columns shrink to fit the available space even when
     --split-left / --split-right are set to fixed/percentage values. Without
     this, `50% 84px 50%` would total 100% + 84px and push the right pane past
     the container's right edge — clipping any right-anchored content. */
  grid-template-columns:
    minmax(0, var(--split-left, 1fr))
    84px
    minmax(0, var(--split-right, 1fr));
  gap: 0;
  /* Grow to fill workspace; clamp keeps editors tall on large screens, usable on small */
  flex: 1 1 auto;
  min-height: clamp(320px, calc(100dvh - 14rem), 960px);
  height: 100%;
  max-height: none;
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 14px;
  overflow: hidden;
  box-shadow: var(--shadow);
}

/* In diff mode the input pane is folded away — A inside the diff viewer
   IS the live input now, so showing the standalone editor as well would
   duplicate the same document on screen. The splitter rail stays (it
   hosts Tree | Format | Diff buttons), but its drag handle is disabled
   in JS since there's nothing to resize against.
   IMPORTANT: when `.pane-input` is `display: none`, CSS Grid skips it for
   auto-placement and the remaining items shift left. So we must declare
   only TWO columns (splitter + output) here — declaring three (with a
   0-width first column) would leave the output pane stuck in column 2 at
   only 84px wide. Same logic applies to the rows in the mobile layout. */
.split-shell[data-diff-mode="true"] {
  grid-template-columns: 84px minmax(0, 1fr);
}

.split-shell[data-diff-mode="true"] .pane-input {
  display: none;
}

/* Splitter handle visually neutral when it can't be dragged. */
.split-shell[data-diff-mode="true"] #splitter {
  cursor: default;
}

@media (max-width: 960px) {
  .split-shell {
    min-height: clamp(280px, calc(100dvh - 15rem), 720px);
  }
}

@media (min-width: 1200px) {
  .split-shell {
    min-height: clamp(400px, calc(100dvh - 12rem), 980px);
  }
}

@media (max-height: 720px) {
  .split-shell {
    min-height: clamp(240px, calc(100dvh - 11rem), 600px);
  }
}

/* Tree-only actions (breadcrumb / path / expand / collapse) — visible in Tree mode only */
.pane-output:not([data-mode="tree"]) .pane-tree-only {
  display: none !important;
}

/* Text-mode actions (minify / wrap / save / apply) — visible in Format/Minify only */
.pane-output:not([data-mode="formatted"]):not([data-mode="minified"]) .pane-text-only {
  display: none !important;
}

/* Diff-only widgets — visible only in Diff mode */
.pane-output:not([data-mode="diff"]) .pane-diff-only {
  display: none !important;
}

/* Hide the global mode chip + breadcrumb container in diff mode — the per-side
   chips inside `.diff-side-overlay` carry clearer labels there. */
.pane-output[data-mode="diff"] .pane-not-diff {
  display: none !important;
}

/* Hide the always-visible Copy button in diff mode (ambiguous: copy A or B?). */
.pane-output[data-mode="diff"] #btnCopyOutput {
  display: none !important;
}

/* Schema mode: the schema editor + errors list owns the right pane, so the
   global Copy button (which is wired to "copy formatted output") doesn't
   make sense — the user is looking at THEIR schema, which Monaco can copy
   via Cmd/Ctrl+A → Cmd/Ctrl+C. */
.pane-output[data-mode="schema"] #btnCopyOutput {
  display: none !important;
}

/* Transform mode: same reasoning as schema — the transform toolbar has its
   own Copy/Download buttons sized to the converted output, so the global
   "copy output" button would be redundant and ambiguous (CSV? YAML?). */
.pane-output[data-mode="transform"] #btnCopyOutput,
.pane-output[data-mode="xslt"] #btnCopyOutput {
  display: none !important;
}

/* ---- Schema view layout ----
   Lives inside `#monacoSchemaHost`. createSchemaView() injects a `.schema-view`
   wrapper containing: schema editor (top, ~60%), a small status row, and a
   scrollable errors list (bottom, ~40%). The `top: 44px` reservation matches
   the floating chip overlay so the schema's first line never sits under it.
   Note: the dialect chip lives on the RIGHT side of the toolbar, so it
   doesn't share an x-column with the top-left pane-chip pill. */
.monaco-host-schema {
  position: absolute;
  inset: 0;
  top: 44px;
}

.schema-view {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  background: var(--pane-bg);
}

/* The toolbar is a thin strip above the schema editor with the
   "Infer from input" + "Reset" actions. We hide it inside a flex
   container so it never gets crowded out when the right pane is small. */
.schema-toolbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.35rem 0.65rem;
  padding-inline-end: max(0.65rem, env(safe-area-inset-right, 0px));
  background: var(--panel-alt);
  border-bottom: 1px solid var(--line);
  font-size: 0.78rem;
  box-sizing: border-box;
}

.schema-toolbar-spacer {
  flex: 1 1 auto;
  min-width: 0;
}

.schema-toolbar-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.35rem;
  background: var(--pane-header-bg);
  border: 1px solid var(--line);
  color: var(--text);
  padding: 0.3rem 0.6rem;
  border-radius: 6px;
  font-size: 0.74rem;
  font-family: inherit;
  cursor: pointer;
  transition: background 80ms ease, border-color 80ms ease;
}

.schema-toolbar-btn:hover,
.schema-toolbar-btn:focus-visible {
  background: var(--button-hover);
  border-color: var(--primary);
  outline: none;
}

.schema-toolbar-btn:active {
  transform: translateY(1px);
}

.schema-toolbar-btn .lucide {
  width: 14px;
  height: 14px;
}

/* Visible error state on the Copy button while the "Copy failed" label is
   showing. We tint the border + text rather than swapping a whole color
   so the button still reads as a button (just unhappy). */
.schema-toolbar-btn.is-error {
  border-color: var(--error);
  color: var(--error);
}

/* Thin vertical rule between toolbar groups (utilities vs. content-changing).
   1px wide, half-height of the button row; uses `--line` so it inherits the
   panel divider color in both themes. */
.schema-toolbar-sep {
  display: inline-block;
  width: 1px;
  height: 18px;
  background: var(--line);
  margin: 0;
  flex: 0 0 auto;
}

/* ---- Dialect picker (chip + popover) ----
   Lives on the LEFT of the toolbar so it reads as a *context* control
   (which dialect am I currently validating against?) rather than a
   one-shot action. The chip surfaces the active label; the caret hints
   at the popover. When the user has forced a dialect we tint the chip
   with the primary color so the override is impossible to miss. */
.schema-dialect {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
}

.schema-dialect-btn {
  /* Inherits .schema-toolbar-btn styles; we only tweak gap + padding to
     fit the extra label + caret in the same vertical rhythm. */
  padding: 0.3rem 0.55rem;
  gap: 0.3rem;
}

.schema-dialect-btn .schema-dialect-caret {
  width: 12px;
  height: 12px;
  opacity: 0.7;
}

.schema-dialect-btn.is-overridden {
  border-color: var(--primary);
  color: var(--primary);
  background: color-mix(in srgb, var(--primary) 14%, var(--button-bg));
}

.schema-dialect-btn.is-overridden .schema-dialect-caret {
  opacity: 1;
}

.schema-dialect-label {
  font-weight: 600;
  letter-spacing: 0.01em;
}

/* The popover floats below the chip. Anchored to the chip's RIGHT edge
   (`right: 0`) because the chip now lives on the right side of the
   toolbar — anchoring left would push the menu off the right edge of
   narrow panes. `min-width` matches the widest option so labels don't
   reflow as the user hovers different rows. `box-shadow` separates it
   from the toolbar without needing a darker background — the panel-alt
   variable already gives it visual weight. */
.schema-dialect-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  z-index: 30;
  min-width: 220px;
  display: flex;
  flex-direction: column;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  padding: 0.25rem;
  overflow: hidden;
}

.schema-dialect-menu[hidden] {
  display: none;
}

.schema-dialect-option {
  display: grid;
  grid-template-columns: 18px 1fr auto;
  align-items: center;
  gap: 0.5rem;
  background: transparent;
  border: 0;
  color: var(--text);
  text-align: left;
  padding: 0.4rem 0.55rem;
  border-radius: 6px;
  font-family: inherit;
  font-size: 0.78rem;
  cursor: pointer;
  transition: background 80ms ease, color 80ms ease;
}

.schema-dialect-option:hover,
.schema-dialect-option:focus-visible {
  background: var(--button-hover);
  outline: none;
}

.schema-dialect-option.is-active {
  color: var(--primary);
}

.schema-dialect-check {
  width: 14px;
  height: 14px;
  visibility: hidden;
}

.schema-dialect-option.is-active .schema-dialect-check {
  visibility: visible;
}

.schema-dialect-option-label {
  font-weight: 600;
}

.schema-dialect-option-hint {
  color: var(--muted);
  font-size: 0.7rem;
  white-space: nowrap;
}

.schema-editor-host {
  flex: 1 1 60%;
  min-height: 100px;
  position: relative;
  border-bottom: 1px solid var(--line);
}

.schema-status {
  flex: 0 0 auto;
  padding: 0.5rem 0.85rem;
  background: var(--panel-alt);
  border-bottom: 1px solid var(--line);
  font-size: 0.78rem;
  color: var(--muted);
  font-family: var(--mono);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.schema-status[data-state="valid"] {
  color: var(--success);
  background: color-mix(in srgb, var(--success) 12%, var(--panel-alt));
}

.schema-status[data-state="invalid"] {
  color: var(--error);
  background: color-mix(in srgb, var(--error) 12%, var(--panel-alt));
}

.schema-status[data-state="schema-error"] {
  color: var(--warning);
  background: color-mix(in srgb, var(--warning) 12%, var(--panel-alt));
}

.schema-status[data-state="input-error"] {
  color: var(--warning);
}

.schema-errors {
  flex: 1 1 40%;
  min-height: 60px;
  overflow-y: auto;
  background: var(--pane-bg);
}

.schema-errors:empty::before {
  content: "No issues to report.";
  display: block;
  padding: 1rem;
  font-size: 0.78rem;
  color: var(--muted);
  font-style: italic;
}

/* Each error row is a button so the whole row is keyboard-focusable; we
   present it as a 3-column grid (line | path | message) so columns align
   even with very long messages. */
.schema-error {
  display: grid;
  grid-template-columns: 64px minmax(120px, 1fr) minmax(180px, 2fr);
  gap: 0.6rem;
  align-items: baseline;
  width: 100%;
  text-align: left;
  padding: 0.5rem 0.75rem;
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--line-soft);
  color: var(--text);
  font-size: 0.78rem;
  font-family: inherit;
  cursor: pointer;
  transition: background 80ms ease;
}

.schema-error:hover,
.schema-error:focus-visible {
  background: var(--button-hover);
  outline: none;
}

.schema-error:focus-visible {
  box-shadow: inset 2px 0 0 var(--primary);
}

.schema-error-line {
  color: var(--muted);
  font-family: var(--mono);
  font-size: 0.72rem;
}

.schema-error-path {
  color: var(--primary);
  font-family: var(--mono);
  word-break: break-all;
}

.schema-error-msg {
  color: var(--text);
  word-break: break-word;
}

/* ---- Transform view layout ----
   Same shape as the schema view (toolbar / Monaco editor / status row),
   minus the errors list — there are no per-row diagnostics to surface,
   only "ok" or "input-error". The `top: 44px` reservation matches the
   floating chip overlay so the first line of converted output never
   sits under the "TRANSFORM" pane-chip pill. */
.monaco-host-transform {
  position: absolute;
  inset: 0;
  top: 44px;
}

/* Standalone transform pages: toolbar lives in .pane-label-bar, not inside the host. */
.pane-output[data-mode="transform"]:has(> .pane-label-bar) .monaco-host-transform {
  top: 0;
}

.pane-output[data-mode="transform"]:has(> .pane-label-bar) .transform-view--pane-toolbar {
  position: absolute;
  inset: 0;
}

.pane-output[data-mode="transform"]:has(> .pane-label-bar) .transform-view--pane-toolbar .transform-editor-host {
  position: absolute;
  inset: 0;
  flex: none;
  min-height: 0;
  border-bottom: none;
}

.pane-output[data-mode="transform"]:has(> .pane-label-bar) .transform-view--pane-toolbar .transform-status {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 2;
  border-top: 1px solid var(--line);
}

.pane-output[data-mode="transform"] > .pane-label-bar .pane-side-tools .transform-target {
  margin-left: auto;
}

.transform-view {
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  background: var(--pane-bg);
}

/* Reuses the schema-toolbar structural styles so the two right-pane
   modes are visually consistent — same chips, same heights, same
   spacing rules. The transform-target popover inherits `.schema-dialect-menu`
   styling for the same reason. */
.transform-toolbar {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.35rem 0.65rem;
  padding-inline-end: max(0.65rem, env(safe-area-inset-right, 0px));
  background: var(--panel-alt);
  border-bottom: 1px solid var(--line);
  font-size: 0.78rem;
  box-sizing: border-box;
}

/* Compact format picker — matches schema-toolbar-btn height (not dialog .text-input). */
.transform-toolbar .transform-select {
  flex: 0 1 auto;
  width: auto;
  max-width: min(200px, 42vw);
  min-width: 0;
  margin: 0;
  padding: 0.28rem 1.55rem 0.28rem 0.5rem;
  font-size: 0.74rem;
  line-height: 1.25;
  font-family: inherit;
  color: var(--text);
  background-color: var(--pane-header-bg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath fill='%2394a3b8' d='M1 1l4 4 4-4'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 0.45rem center;
  background-size: 0.55rem auto;
  border: 1px solid var(--line);
  border-radius: 6px;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
}

.transform-toolbar .transform-select:hover {
  border-color: color-mix(in srgb, var(--primary) 45%, var(--line));
}

.transform-toolbar .transform-select:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 2px var(--primary-soft);
}

.transform-toolbar .transform-convert-btn {
  flex-shrink: 0;
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}

.transform-toolbar .transform-convert-btn:hover,
.transform-toolbar .transform-convert-btn:focus-visible {
  background: var(--primary-hover);
  border-color: var(--primary-hover);
  color: #fff;
}

/* ---- XSLT playground (split stylesheet / output) ---- */
.xslt-playground {
  position: absolute;
  inset: 0;
  top: 44px;
  display: flex;
  flex-direction: column;
  height: auto;
  width: 100%;
  background: var(--pane-bg);
}

.pane-output.is-fullscreen[data-mode="xslt"] .xslt-playground {
  top: clamp(2.65rem, 2rem + env(safe-area-inset-top, 0px), 3.1rem);
}

.xslt-playground .xslt-hint {
  flex: 1 1 auto;
  min-width: 0;
  font-size: 0.72rem;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.xslt-split {
  flex: 1 1 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  min-height: 120px;
  border-top: 1px solid var(--line);
}

.xslt-pane {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  border-right: 1px solid var(--line);
}

.xslt-pane:last-child {
  border-right: 0;
}

.xslt-pane-label {
  flex: 0 0 auto;
  padding: 0.28rem 0.55rem;
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--panel-alt);
  border-bottom: 1px solid var(--line);
}

.xslt-editor-host {
  flex: 1 1 auto;
  position: relative;
  min-height: 80px;
}

/* Copy overlay on nested Monaco hosts (transform / XSLT panes). */
.transform-editor-host,
.xslt-editor-host,
.monaco-host-transform .transform-view > div > div:last-child {
  position: relative;
}

.editor-copy-overlay {
  z-index: 12;
}

@media (max-width: 720px) {
  .xslt-split {
    grid-template-columns: 1fr;
    grid-template-rows: 1fr 1fr;
  }
  .xslt-pane {
    border-right: 0;
    border-bottom: 1px solid var(--line);
  }
  .xslt-pane:last-child {
    border-bottom: 0;
  }
  .xslt-playground .xslt-hint {
    display: none;
  }
}

.transform-target {
  position: relative;
  display: inline-flex;
  flex: 0 0 auto;
}

/* The transform target chip lives on the RIGHT side of the toolbar
   (just before Copy / Download — the actions it influences), so the
   popover inherits the schema-dialect-menu's `right: 0` anchor without
   override. Anchoring left here would push the menu off the pane edge
   on narrow widths. */

.transform-editor-host {
  flex: 1 1 auto;
  min-height: 100px;
  position: relative;
  border-bottom: 1px solid var(--line);
}

.transform-status {
  flex: 0 0 auto;
  padding: 0.5rem 0.85rem;
  background: var(--panel-alt);
  font-size: 0.78rem;
  color: var(--muted);
  font-family: var(--mono);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.transform-status[data-state="ok"] {
  color: var(--success);
  background: color-mix(in srgb, var(--success) 12%, var(--panel-alt));
}

.transform-status[data-state="input-error"],
.transform-status[data-state="error"] {
  color: var(--warning);
  background: color-mix(in srgb, var(--warning) 12%, var(--panel-alt));
}

/* ---- Per-side diff toolbars ----
   Each toolbar covers half the pane horizontally so A controls live above
   the A editor and B controls live above the B editor. The container is
   pointer-events:none so empty space passes through to Monaco; only the
   chips/buttons themselves are interactive. */
.diff-side-overlay {
  position: absolute;
  top: 0.5rem;
  z-index: 6;
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0 0.6rem;
  width: 50%;
  min-width: 0;
  pointer-events: none;
}

.diff-side-overlay > * {
  pointer-events: auto;
}

.diff-side-a {
  left: 0;
  justify-content: flex-start;
}

/* B sits in the right half; chip + buttons left-aligned at the half-line.
   The `.diff-toolbar-spacer` then pushes the global Paste/Swap/Clear over
   to the far-right edge of the pane. */
.diff-side-b {
  right: 0;
  justify-content: flex-start;
}

.diff-toolbar-spacer {
  flex: 1 1 auto;
  min-width: 0.3rem;
}

/* Side label chip — slightly different color to signal "section header". */
.diff-side-chip {
  letter-spacing: 0.06em;
  flex: 0 0 auto;
}

.pane {
  display: flex;
  flex-direction: column;
  min-width: 0;
  min-height: 0;
  background: var(--pane-bg);
  position: relative;
}

.pane + .pane {
  border-left: 1px solid var(--line);
}

/* ── Pane label bar — sits above the Monaco host, not overlaid on it ─── */
.pane-label-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-shrink: 0;
  padding: 0.28rem 0.75rem;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
  gap: 0.4rem;
  /* Match bar height across input/output so Monaco hosts start on the same row */
  min-height: calc(26px + 0.56rem);
  box-sizing: border-box;
}

.pane-label-bar-actions {
  display: flex;
  align-items: center;
  gap: 0.1rem;
  margin-left: auto;
  flex: 0 0 auto;
}

/* Icon tools inline with the pane chip (json-diff / standalone tool pages). */
.pane-label-bar .pane-chip {
  flex: 0 0 auto;
}

.pane-side-tools {
  display: flex;
  align-items: center;
  gap: 0.12rem;
  flex: 1 1 auto;
  min-width: 0;
  margin-left: 0.2rem;
}

.overlay-btn.overlay-btn-text {
  width: auto;
  min-width: 26px;
  padding: 0 0.38rem;
  font-size: 0.68rem;
  font-weight: 600;
  font-family: var(--mono);
  letter-spacing: 0;
}

/* ---- In-editor floating overlays (chips + actions baked into the editor) ---- */
.pane-overlay {
  position: absolute;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 0.3rem;
  pointer-events: none; /* let clicks fall through empty overlay space */
  min-width: 0;
}

.pane-overlay > * {
  pointer-events: auto; /* but the chips/buttons themselves remain clickable */
}

/* Top-left chip + (in tree mode) breadcrumb. 70% gives the scrollable breadcrumb
   plenty of room; the TR toolbar only ever contains a handful of icon buttons
   (~130 px) so it doesn't need half the pane reserved for it. */
.pane-overlay-tl {
  top: 0.45rem;
  left: 0.55rem;
  max-width: calc(70% - 0.6rem);
  flex-wrap: nowrap; /* breadcrumb scrolls horizontally; no need to wrap */
  min-width: 0;
}

/* Top-right action toolbar. Anchored at right; grows leftward up to max-width.
   flex-wrap lets buttons reflow onto a 2nd row on very narrow panes. */
.pane-overlay-tr {
  top: 0.45rem;
  right: 0.55rem;
  flex-wrap: wrap;
  justify-content: flex-end;
  max-width: calc(50% - 0.6rem);
}

.pane-chip {
  font-size: 0.65rem;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  background: var(--pane-header-bg);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  padding: 0.2rem 0.6rem;
  white-space: nowrap;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 0;
  font-family: var(--mono);
  font-size: 0.7rem;
  background: var(--pane-header-bg);
  border: 1px solid var(--line-soft);
  border-radius: 999px;
  padding: 0.18rem 0.55rem;
  min-width: 0;
  flex: 1 1 0;
  overflow-x: auto;
  scrollbar-width: none; /* Firefox */
  white-space: nowrap;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}
.breadcrumb::-webkit-scrollbar { display: none; }

.bc-seg {
  flex-shrink: 0;
  white-space: nowrap;
}
.bc-seg.bc-root { color: var(--muted); }
.bc-seg.bc-key  { color: var(--text); }
.bc-seg.bc-index { color: var(--primary); }

.bc-arrow {
  flex-shrink: 0;
  padding: 0 0.18rem;
  color: var(--muted);
  font-size: 0.65rem;
  opacity: 0.6;
  user-select: none;
}

/* Breadcrumb path segments — buttons match XML tree header behaviour */
.breadcrumb button.bc-seg {
  border: none;
  background: transparent;
  font: inherit;
  font-size: inherit;
  line-height: inherit;
  padding: 0 0.05rem;
  margin: 0;
  cursor: pointer;
  border-radius: 4px;
  /* Let long keys show in full; horizontal scroll on `.breadcrumb` handles overflow. */
  max-width: none;
  overflow: visible;
  text-overflow: clip;
}
.breadcrumb button.bc-seg:hover {
  text-decoration: underline;
  color: var(--primary);
}
.breadcrumb button.bc-seg:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

/* Icon-only square button used in the floating toolbars. SVGs inside use
   currentColor so they pick up theme + active/hover state automatically. */
.overlay-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid var(--line-soft);
  background: var(--pane-header-bg);
  color: var(--muted);
  border-radius: 6px;
  cursor: pointer;
  flex: 0 0 auto;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease, transform 0.08s ease;
}

.overlay-btn svg {
  width: 14px;
  height: 14px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}

.overlay-btn:hover {
  color: var(--text-strong);
  border-color: var(--primary);
  background: var(--button-hover);
}

.overlay-btn:active {
  transform: translateY(1px);
}

.overlay-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.overlay-btn[aria-pressed="true"],
.overlay-btn.is-active {
  background: var(--primary-soft);
  border-color: var(--primary);
  color: var(--text-strong);
}

.pane-body {
  flex: 1;
  position: relative;
  min-height: 0;
  background: var(--code-bg);
  /* Safety net: floating overlays + Monaco are constrained to the pane.
     Monaco hover/suggestion popups still render OK because we use
     `fixedOverflowWidgets: true` (they mount at the document root). */
  overflow: hidden;
}

/* Tree: JSONEditor context menus + Type/Insert submenus live inside the editor
   frame; `overflow: hidden` on `.pane-body` was clipping everything below the
   first group (Insert / Duplicate / Remove) and any expanded submenu. */
.pane-output[data-mode="tree"] .pane-body {
  overflow: visible;
}

.monaco-host,
.tree-host {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Reserve space at the top of the JSONEditor tree for our floating chip +
   action toolbar. (For Monaco we use the editor's `padding.top` option
   instead — that keeps the gutter/scrollbar layout correct.) */
.tree-host {
  top: 44px;
  height: auto;
  bottom: 0;
  background: var(--tree-bg);
}

.pane-loader {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: var(--code-bg);
  color: var(--muted);
  font-size: 0.85rem;
  text-align: center;
  z-index: 2;
}

.pane-loader-muted {
  background: var(--tree-bg);
  border-left: 0;
}

.pane-loader p {
  margin: 0.5rem 0 0;
}

.spinner {
  width: 22px;
  height: 22px;
  border-radius: 50%;
  border: 2px solid var(--line);
  border-top-color: var(--primary);
  animation: spin 0.7s linear infinite;
}

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

/* ── JSON error decorations (glyph margin ✕ + line highlight) ─────────── */

/* Full-line red tint behind the error row */
.json-error-line-highlight {
  background: rgba(244, 71, 71, 0.10);
  border-left: 2px solid rgba(244, 71, 71, 0.7);
}

/* Bold ✕ in the glyph margin column */
.json-error-glyph {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
}
.json-error-glyph::before {
  content: "\2715"; /* ✕ */
  color: #f44747;
  font-weight: 900;
  font-size: 13px;
  line-height: 1;
}

[data-theme="light"] .json-error-line-highlight {
  background: rgba(210, 63, 51, 0.08);
  border-left: 2px solid rgba(210, 63, 51, 0.6);
}
[data-theme="light"] .json-error-glyph::before {
  color: #d23f33;
}

/* ────────────────────────────────────────────────────────────────────────── */

/* Splitter — also hosts the Tree / Format / Minify rail */
.splitter {
  background: var(--pane-header-bg);
  cursor: col-resize;
  position: relative;
  border-left: 1px solid var(--line);
  border-right: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0.5rem 0.4rem;
  transition: background 0.15s ease;
}

.splitter:hover,
.splitter.is-dragging {
  background: var(--button-hover);
}

.splitter:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}

.splitter-rail {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
  width: 100%;
  cursor: default;
}

.splitter-btn {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.15rem;
  padding: 0.55rem 0.25rem;
  border: 1px solid var(--line);
  background: var(--panel-alt);
  color: var(--muted);
  border-radius: 9px;
  font-size: 0.7rem;
  font-weight: 500;
  cursor: pointer;
  transition: background 0.12s ease, border-color 0.12s ease, color 0.12s ease, transform 0.05s ease;
  width: 100%;
  min-height: 56px;
  line-height: 1.1;
}

.splitter-btn:hover {
  color: var(--text);
  border-color: var(--primary);
  background: color-mix(in srgb, var(--primary) 10%, var(--panel-alt) 90%);
}

.splitter-btn:active {
  transform: scale(0.97);
}

.splitter-btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 1px;
}

.splitter-btn.is-active {
  background: var(--primary);
  border-color: var(--primary);
  color: #ffffff;
  box-shadow: 0 4px 12px color-mix(in srgb, var(--primary) 40%, transparent 60%);
}

.splitter-btn.is-active:hover {
  background: var(--primary-hover);
  border-color: var(--primary-hover);
}

.splitter-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 1.15rem;
  height: 1.15rem;
  color: inherit;
}

.splitter-label {
  font-size: 0.72rem;
  letter-spacing: 0.02em;
}

/* =========================================================================
   Output pane — fullscreen mode
   ========================================================================= */

.pane-output.is-fullscreen {
  position: fixed;
  inset: 0;
  z-index: 9000;
  border-radius: 0;
  width: 100vw !important;
  height: 100dvh !important;
  max-width: none;
  max-height: none;
}

.pane-output.is-fullscreen::before {
  content: none;
}

/* Keep the overlay buttons visible over the fullscreen content */
.pane-output.is-fullscreen .pane-overlay {
  z-index: 9001;
}

/* In fullscreen, keep the breadcrumb visible (matches XML editor; path is not duplicated elsewhere). */
.pane-output.is-fullscreen .pane-overlay-tr {
  right: 1rem;
  top: 0.55rem;
}

.pane-output.is-fullscreen .pane-overlay-tl {
  left: 1rem;
  top: 0.55rem;
}

/* Toolbar modes: expand/collapse lives in the mode toolbar (syncFullscreenButton.js). */
.pane-output[data-mode="schema"] .pane-overlay-tr,
.pane-output[data-mode="transform"] .pane-overlay-tr,
.pane-output[data-mode="xslt"] .pane-overlay-tr,
.pane-output[data-mode="xpath"] .pane-overlay-tr,
.pane-output[data-mode="validate"] .pane-overlay-tr {
  display: none !important;
}

.pane-output[data-mode="schema"] .schema-toolbar .schema-toolbar-btn,
.pane-output[data-mode="transform"] .transform-toolbar .schema-toolbar-btn,
.pane-output[data-mode="xpath"] .schema-toolbar .schema-toolbar-btn {
  flex-shrink: 0;
}

/* Fullscreen: hosts sit below the mode chip row; toolbars need extra end inset. */
.pane-output.is-fullscreen[data-mode="schema"] .monaco-host-schema,
.pane-output.is-fullscreen[data-mode="transform"] .monaco-host-transform {
  top: clamp(2.75rem, calc(2.15rem + env(safe-area-inset-top, 0px)), 3.2rem);
}

.pane-output.is-fullscreen[data-mode="schema"] .schema-toolbar,
.pane-output.is-fullscreen[data-mode="transform"] .transform-toolbar,
.pane-output.is-fullscreen[data-mode="xslt"] .transform-toolbar,
.pane-output.is-fullscreen[data-mode="xpath"] .schema-toolbar {
  flex-wrap: wrap;
  row-gap: 0.3rem;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  padding-inline-start: max(0.75rem, env(safe-area-inset-left, 0px));
  padding-inline-end: max(1.15rem, calc(0.9rem + env(safe-area-inset-right, 0px)));
}

.pane-output.is-fullscreen[data-mode="xslt"] .xslt-hint {
  display: none;
}

/* Expand control at the end of a mode toolbar (icon-only, same height as peers) */
.schema-toolbar .toolbar-fullscreen-btn,
.transform-toolbar .toolbar-fullscreen-btn {
  flex-shrink: 0;
  margin: 0;
  padding: 0.3rem 0.45rem;
  min-width: 2rem;
  box-sizing: border-box;
}

.pane-output.is-fullscreen[data-mode="schema"] .schema-toolbar .toolbar-fullscreen-btn,
.pane-output.is-fullscreen[data-mode="transform"] .transform-toolbar .toolbar-fullscreen-btn,
.pane-output.is-fullscreen[data-mode="xslt"] .transform-toolbar .toolbar-fullscreen-btn,
.pane-output.is-fullscreen[data-mode="xpath"] .schema-toolbar .toolbar-fullscreen-btn {
  margin-inline-end: 0.05rem;
}

.schema-toolbar .toolbar-fullscreen-btn svg,
.transform-toolbar .toolbar-fullscreen-btn svg {
  width: 14px;
  height: 14px;
  display: block;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  pointer-events: none;
}


/* Fullscreen tree: fluid insets + shared vertical rhythm (search / chip / path / tree). */
.pane-output.is-fullscreen[data-mode="tree"] {
  --fs-tree-top-inset: clamp(
    calc(0.32rem + env(safe-area-inset-top, 0px)),
    calc(0.22rem + 1.1vw + env(safe-area-inset-top, 0px)),
    calc(0.55rem + env(safe-area-inset-top, 0px))
  );
  --fs-tree-tl-right: clamp(4.35rem, 2.75rem + 12vw, 8.75rem);
  --fs-tree-chip-breadcrumb-gap: clamp(0.55rem, 0.35rem + 1.8vw, 1.05rem);
  --fs-tree-pill-row: clamp(1.65rem, 1.05rem + 2.2vw, 2.35rem);
  --fs-tree-row-gap: clamp(0.26rem, 0.2rem + 0.6vw, 0.45rem);
}

/* Fullscreen tree: TREE chip on row 1, path on row 2 — keeps the centered search
   from sitting on top of a long breadcrumb (JSON + XML share this layout). */
.pane-output.is-fullscreen[data-mode="tree"] .pane-overlay-tl {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--fs-tree-row-gap);
  left: clamp(0.42rem, 0.35rem + 1.4vw, 1rem);
  top: var(--fs-tree-top-inset);
  /* Reserve the top-right icon rail; vw term keeps phones from running under buttons. */
  max-width: none;
  right: var(--fs-tree-tl-right);
  width: auto;
}

.pane-output.is-fullscreen[data-mode="tree"] .pane-overlay-tl .breadcrumb {
  flex: 0 1 auto;
  width: 100%;
  max-width: 100%;
}

/* Row 2 was placed directly under the short TREE chip; the centered search bar is taller,
   so the path sat under the search box + shadow. Nudge the path down to clear that band. */
.pane-output.is-fullscreen[data-mode="tree"] .pane-overlay-tl .pane-chip + .breadcrumb {
  margin-top: var(--fs-tree-chip-breadcrumb-gap);
}

/* Fullscreen tree: TL is two rows (chip + path). Default `top: 44px` on `.tree-host`
   only clears one row — push the JSONEditor frame down so the root row isn't under the breadcrumb. */
.pane-output.is-fullscreen[data-mode="tree"] .tree-host {
  top: calc(
    var(--fs-tree-top-inset)
    + var(--fs-tree-pill-row)
    + var(--fs-tree-row-gap)
    + var(--fs-tree-pill-row)
    + var(--fs-tree-row-gap)
    + var(--fs-tree-chip-breadcrumb-gap)
  );
}

/* ── Fullscreen tree search — centered top band (visually same row as TREE chip + TR toolbar) ─ */
.fs-search-bar {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  top: 0.55rem;
  z-index: 9010;
  width: min(480px, calc(100% - 300px));
}

/* Compact search in fullscreen tree: scales down on narrow viewports; width never overruns rails. */
.pane-output.is-fullscreen[data-mode="tree"] .fs-search-bar {
  top: var(--fs-tree-top-inset);
  width: min(
    clamp(11.5rem, 36vw + 6rem, 20rem),
    calc(100% - clamp(6.25rem, 22vw + 2.5rem, 11rem))
  );
  max-width: calc(
    100vw - env(safe-area-inset-left, 0px) - env(safe-area-inset-right, 0px) - 1rem
  );
}

.pane-output.is-fullscreen[data-mode="tree"] .fs-search-inner {
  height: clamp(24px, 1.35rem + 0.6vw, 28px);
  padding: clamp(0.06rem, 0.1vw + 0.04rem, 0.12rem) clamp(0.22rem, 0.35vw + 0.18rem, 0.35rem);
  border-radius: clamp(5px, 0.35rem + 0.2vw, 7px);
  box-shadow: 0 2px clamp(8px, 1.5vw + 4px, 12px) rgba(0, 0, 0, 0.28);
}

.pane-output.is-fullscreen[data-mode="tree"] .fs-search-input {
  font-size: clamp(0.72rem, 0.65rem + 0.35vw, 0.82rem);
}

.pane-output.is-fullscreen[data-mode="tree"] .fs-search-icon {
  width: clamp(0.78rem, 0.72rem + 0.35vw, 0.9rem);
  height: clamp(0.78rem, 0.72rem + 0.35vw, 0.9rem);
}

.pane-output.is-fullscreen[data-mode="tree"] .fs-search-count {
  font-size: clamp(0.62rem, 0.58rem + 0.25vw, 0.72rem);
  min-width: clamp(2rem, 1.6rem + 1.5vw, 2.5rem);
}

.pane-output.is-fullscreen[data-mode="tree"] .fs-search-nav {
  width: clamp(20px, 1.1rem + 1.1vw, 24px);
  height: clamp(20px, 1.1rem + 1.1vw, 24px);
  border-radius: clamp(4px, 0.28rem + 0.2vw, 6px);
}

.pane-output.is-fullscreen[data-mode="tree"] .fs-search-bar:not([hidden]) {
  display: block;
}

.pane-output:not(.is-fullscreen) .fs-search-bar,
.pane-output:not([data-mode="tree"]) .fs-search-bar {
  display: none !important;
}

.fs-search-inner {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 8px;
  padding: 0.25rem 0.45rem;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.45);
  backdrop-filter: blur(6px);
  height: 30px;
  box-sizing: border-box;
}

.fs-search-icon {
  display: inline-flex;
  align-items: center;
  color: var(--muted);
  flex: 0 0 auto;
  width: 1rem;
  height: 1rem;
}

.fs-search-input {
  flex: 1 1 0;
  min-width: 0;
  background: transparent;
  border: none;
  outline: none;
  color: var(--text);
  font-size: 0.875rem;
  font-family: var(--mono);
  padding: 0.1rem 0.25rem;
}

.fs-search-input::placeholder {
  color: var(--muted);
}

.fs-search-count {
  font-size: 0.75rem;
  color: var(--muted);
  white-space: nowrap;
  flex: 0 0 auto;
  min-width: 3rem;
  text-align: right;
}

.fs-search-nav {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  border: 1px solid var(--line);
  border-radius: 6px;
  background: var(--panel-alt);
  color: var(--muted);
  cursor: pointer;
  flex: 0 0 auto;
  transition: background 0.12s, color 0.12s;
}

.fs-search-nav:hover {
  background: var(--button-hover);
  color: var(--text);
}

/* Fullscreen button glows when active */
#btnFullscreenOutput.is-active {
  color: var(--primary);
  border-color: var(--primary);
}

/* =========================================================================
   Status bar
   ========================================================================= */

.statusbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.8rem;
  padding: 0.28rem 0.95rem;
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 12px;
  font-size: 0.78rem;
  color: var(--muted);
  flex-wrap: wrap;
}

.statusbar-left,
.statusbar-right {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  min-width: 0;
}

.status-pill {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.3rem 0.65rem;
  border-radius: 999px;
  background: var(--panel-alt);
  border: 1px solid var(--line);
  color: var(--text);
  font-size: 0.78rem;
  font-weight: 500;
}

.status-dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--muted);
  box-shadow: 0 0 0 0 currentColor;
}

.status-pill[data-tone="success"] {
  color: var(--success);
  border-color: color-mix(in srgb, var(--success) 35%, var(--line) 65%);
}

.status-pill[data-tone="success"] .status-dot {
  background: var(--success);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--success) 25%, transparent 75%);
}

.status-pill[data-tone="error"] {
  color: var(--error);
  border-color: color-mix(in srgb, var(--error) 35%, var(--line) 65%);
}

.status-pill[data-tone="error"] .status-dot {
  background: var(--error);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--error) 25%, transparent 75%);
}

.status-pill[data-tone="warning"] {
  color: var(--warning);
  border-color: color-mix(in srgb, var(--warning) 35%, var(--line) 65%);
}

.status-pill[data-tone="warning"] .status-dot {
  background: var(--warning);
  animation: pulse 1.2s ease-in-out infinite;
}

@keyframes pulse {
  0%, 100% { opacity: 1; }
  50% { opacity: 0.45; }
}

.status-error {
  font-family: var(--mono);
  color: var(--error);
  font-size: 0.78rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 60vw;
}

.status-meta {
  font-variant-numeric: tabular-nums;
}

.status-fix-btn {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  padding: 0.12rem 0.5rem;
  border: 1px solid var(--warning);
  border-radius: 999px;
  background: transparent;
  color: var(--warning);
  font-size: 0.7rem;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
  flex-shrink: 0;
  transition: background 0.12s, color 0.12s;
}
.status-fix-btn:hover {
  background: var(--warning);
  color: #000;
}
.status-fix-btn .lucide {
  width: 11px;
  height: 11px;
  flex-shrink: 0;
}

/* =========================================================================
   Nav dropdowns (Features / Settings / Help)
   ========================================================================= */

.nav-drops {
  display: flex;
  align-items: center;
  gap: 0.15rem;
}

.nav-drop {
  position: relative;
}

.nav-drop-trigger {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.3rem 0.65rem;
  border-radius: 6px;
  border: 1px solid transparent;
  background: transparent;
  color: var(--text);
  font-size: 0.8rem;
  font-weight: 500;
  cursor: pointer;
  white-space: nowrap;
  transition: background 0.12s, border-color 0.12s, color 0.12s;
}
.nav-drop-trigger:hover,
.nav-drop.is-open .nav-drop-trigger {
  background: var(--button-hover);
  border-color: var(--line-soft);
  color: var(--text-strong);
}
.nav-drop-chevron {
  width: 12px;
  height: 12px;
  flex-shrink: 0;
  transition: transform 0.15s;
}
.nav-drop.is-open .nav-drop-chevron {
  transform: rotate(180deg);
}

.nav-drop-menu {
  display: none;
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  min-width: 220px;
  background: var(--tooltip-bg);
  border: 1px solid var(--line);
  border-radius: 8px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
  padding: 0.35rem 0;
  z-index: 200;
  animation: dropIn 0.12s ease;
}
.nav-drop-menu-help {
  min-width: 260px;
}
.nav-drop.is-open .nav-drop-menu {
  display: block;
}

@keyframes dropIn {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}

.nav-drop-item {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  width: 100%;
  padding: 0.45rem 0.85rem;
  background: transparent;
  border: none;
  color: var(--text);
  font-size: 0.82rem;
  text-align: left;
  cursor: pointer;
  text-decoration: none;
  transition: background 0.1s, color 0.1s;
  border-radius: 0;
}
.nav-drop-item:hover {
  background: var(--primary-soft);
  color: var(--text-strong);
}
.nav-drop-item .lucide {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  opacity: 0.75;
}

.nav-drop-label {
  flex: 1 1 auto;
  font-weight: 500;
}

.nav-drop-meta {
  font-size: 0.7rem;
  color: var(--muted);
  white-space: nowrap;
  margin-left: auto;
  padding-left: 0.5rem;
}

.nav-drop-divider {
  height: 1px;
  background: var(--line);
  margin: 0.3rem 0;
}

.nav-drop-section {
  padding: 0.35rem 0.85rem 0.15rem;
  font-size: 0.65rem;
  font-weight: 700;
  letter-spacing: 0.07em;
  text-transform: uppercase;
  color: var(--muted);
}

/* Theme check marks — only the active theme shows its check */
.nav-drop-check {
  width: 13px;
  height: 13px;
  flex-shrink: 0;
  color: var(--primary);
  opacity: 0;
  transition: opacity 0.1s;
}
.nav-drop-check.is-checked {
  opacity: 1;
}

/* Font size row */
.nav-drop-font-row {
  display: flex;
  align-items: center;
  gap: 0.3rem;
  padding: 0.4rem 0.85rem 0.5rem;
}
.font-sz-btn {
  flex: 1 1 0;
  padding: 0.3rem 0;
  border: 1px solid var(--line);
  border-radius: 5px;
  background: var(--button-bg);
  color: var(--text);
  font-size: 0.75rem;
  font-family: inherit;
  cursor: pointer;
  text-align: center;
  transition: background 0.1s, border-color 0.1s, color 0.1s;
}
.font-sz-btn:hover {
  background: var(--button-hover);
  color: var(--text-strong);
}
.font-sz-btn.is-active {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
  font-weight: 600;
}

/* Keyboard shortcuts mini-grid inside Help dropdown */
.nav-drop-shortcuts {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.3rem 0.6rem;
  padding: 0.35rem 0.85rem 0.5rem;
  align-items: center;
}
.sc-key kbd {
  display: inline-block;
  padding: 0.1rem 0.35rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--button-bg);
  font-size: 0.68rem;
  font-family: var(--mono);
  color: var(--text);
  white-space: nowrap;
}
.sc-desc {
  font-size: 0.76rem;
  color: var(--muted);
}

/* ── Color swatches ────────────────────────────────────────────────────── */

.nav-drop-color-row {
  display: flex;
  gap: 0.45rem;
  padding: 0.4rem 0.85rem 0.6rem;
  flex-wrap: wrap;
}

.color-swatch {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  border: 2px solid rgba(255, 255, 255, 0.12);
  cursor: pointer;
  position: relative;
  transition: transform 0.12s, box-shadow 0.12s;
  flex-shrink: 0;
  padding: 0;
}
.color-swatch:hover {
  transform: scale(1.2);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.4);
}
.color-swatch.is-active {
  box-shadow: 0 0 0 2px rgba(255, 255, 255, 0.8), 0 0 0 4px rgba(0, 0, 0, 0.35);
}
/* Checkmark on active swatch via border-trick */
.color-swatch.is-active::after {
  content: '';
  position: absolute;
  left: 7px;
  top: 3px;
  width: 5px;
  height: 9px;
  border-right: 2.5px solid #fff;
  border-bottom: 2.5px solid #fff;
  transform: rotate(40deg);
}

/* =========================================================================
   Accent colour palettes
   Each palette sets background + panel tones + primary colour for both
   dark and light themes. Applied via data-accent on <html>.
   ========================================================================= */

/* ── Blue Night ─── */
[data-theme="dark"][data-accent="blue-night"] {
  --bg: #0d1117;
  --bg-grad: radial-gradient(circle at top right, #1a2740 0%, #0d1117 45%, #070c13 100%);
  --panel: #161b22;
  --panel-alt: #21262d;
  --panel-deep: #13181f;
  --splitter-bg: #21262d;
  --primary: #58a6ff;
  --primary-hover: #79b8ff;
  --primary-soft: rgba(88, 166, 255, 0.18);
}
[data-theme="light"][data-accent="blue-night"] {
  --bg: #e8f4ff;
  --bg-grad: radial-gradient(circle at top right, #d0e9ff 0%, #e8f4ff 45%, #c8e3ff 100%);
  --panel: #f4faff;
  --panel-alt: #e4f2ff;
  --panel-deep: #f8fcff;
  --splitter-bg: #d4ecff;
  --primary: #0969da;
  --primary-hover: #0558c1;
  --primary-soft: rgba(9, 105, 218, 0.12);
}

/* ── Forest ─── */
[data-theme="dark"][data-accent="forest"] {
  --bg: #0d1510;
  --bg-grad: radial-gradient(circle at top right, #182818 0%, #0d1510 45%, #080d09 100%);
  --panel: #141e16;
  --panel-alt: #1c2b1e;
  --panel-deep: #111912;
  --splitter-bg: #1c2b1e;
  --primary: #3fb950;
  --primary-hover: #56c966;
  --primary-soft: rgba(63, 185, 80, 0.18);
}
[data-theme="light"][data-accent="forest"] {
  --bg: #f0fdf4;
  --bg-grad: radial-gradient(circle at top right, #d9f5e3 0%, #f0fdf4 45%, #d1fadf 100%);
  --panel: #f7fff9;
  --panel-alt: #e6f9ec;
  --panel-deep: #f2fef5;
  --splitter-bg: #d4f5de;
  --primary: #16a34a;
  --primary-hover: #15803d;
  --primary-soft: rgba(22, 163, 74, 0.12);
}

/* ── Violet ─── */
[data-theme="dark"][data-accent="violet"] {
  --bg: #150d1f;
  --bg-grad: radial-gradient(circle at top right, #261338 0%, #150d1f 45%, #0e0812 100%);
  --panel: #1d1230;
  --panel-alt: #271a3d;
  --panel-deep: #180f28;
  --splitter-bg: #271a3d;
  --primary: #a78bfa;
  --primary-hover: #b89ffb;
  --primary-soft: rgba(167, 139, 250, 0.18);
}
[data-theme="light"][data-accent="violet"] {
  --bg: #faf5ff;
  --bg-grad: radial-gradient(circle at top right, #ede9fe 0%, #faf5ff 45%, #e8e0fc 100%);
  --panel: #fdf9ff;
  --panel-alt: #f3eafe;
  --panel-deep: #faf5ff;
  --splitter-bg: #e8d8fc;
  --primary: #7c3aed;
  --primary-hover: #6d28d9;
  --primary-soft: rgba(124, 58, 237, 0.12);
}

/* ── Amber ─── */
[data-theme="dark"][data-accent="amber"] {
  --bg: #1a1407;
  --bg-grad: radial-gradient(circle at top right, #2c220d 0%, #1a1407 45%, #0f0c04 100%);
  --panel: #221c09;
  --panel-alt: #2e260e;
  --panel-deep: #1c1708;
  --splitter-bg: #2e260e;
  --primary: #f59e0b;
  --primary-hover: #fbbf24;
  --primary-soft: rgba(245, 158, 11, 0.18);
}
[data-theme="light"][data-accent="amber"] {
  --bg: #fffbeb;
  --bg-grad: radial-gradient(circle at top right, #fde68a 0%, #fffbeb 45%, #fef3c7 100%);
  --panel: #fffef5;
  --panel-alt: #fef9dc;
  --panel-deep: #fffef8;
  --splitter-bg: #fde68a;
  --primary: #d97706;
  --primary-hover: #b45309;
  --primary-soft: rgba(217, 119, 6, 0.12);
}

/* ── Rose ─── */
[data-theme="dark"][data-accent="rose"] {
  --bg: #1a0d10;
  --bg-grad: radial-gradient(circle at top right, #2d1218 0%, #1a0d10 45%, #10080a 100%);
  --panel: #220f14;
  --panel-alt: #2d151e;
  --panel-deep: #1c0c11;
  --splitter-bg: #2d151e;
  --primary: #fb7185;
  --primary-hover: #f43f5e;
  --primary-soft: rgba(251, 113, 133, 0.18);
}
[data-theme="light"][data-accent="rose"] {
  --bg: #fff1f3;
  --bg-grad: radial-gradient(circle at top right, #ffe4e6 0%, #fff1f3 45%, #ffd6da 100%);
  --panel: #fff5f7;
  --panel-alt: #ffe8ec;
  --panel-deep: #fff5f7;
  --splitter-bg: #ffd0d6;
  --primary: #e11d48;
  --primary-hover: #be123c;
  --primary-soft: rgba(225, 29, 72, 0.12);
}

/* ── Sage ─── */
[data-theme="dark"][data-accent="sage"] {
  --bg: #0c1410;
  --bg-grad: radial-gradient(circle at top right, #1a2e1a 0%, #0c1410 45%, #081008 100%);
  --panel: #121f13;
  --panel-alt: #1a2e1a;
  --panel-deep: #0f1a10;
  --splitter-bg: #1a2e1a;
  --primary: #4caf50;
  --primary-hover: #66bb6a;
  --primary-soft: rgba(76, 175, 80, 0.18);
}
[data-theme="light"][data-accent="sage"] {
  --bg: #f2fbf2;
  --bg-grad: radial-gradient(circle at top right, #c8ecc8 0%, #f2fbf2 45%, #d4f0d4 100%);
  --panel: #f8fff8;
  --panel-alt: #e2f5e2;
  --panel-deep: #f5fef5;
  --splitter-bg: #c8ecc8;
  --primary: #319331;
  --primary-hover: #267326;
  --primary-soft: rgba(49, 147, 49, 0.12);
}

/* =========================================================================
   Features overview section
   ========================================================================= */

.features-overview {
  padding: 0.95rem 1rem 1.05rem;
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 10px;
  margin-top: 1rem;
}

.features-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: 0.75rem;
  margin-top: 0.85rem;
}

.feature-card {
  /* 2-row grid: icon spans both rows left, title + description stack right */
  display: grid;
  grid-template-columns: auto 1fr;
  grid-template-rows: auto auto;
  column-gap: 0.75rem;
  row-gap: 0.2rem;
  align-items: start;
  padding: 0.85rem 1rem;
  background: var(--panel-alt);
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  transition: border-color 0.15s, background 0.15s;
}
.feature-card:hover {
  border-color: var(--primary);
  background: var(--panel-deep);
}

.feature-icon {
  grid-column: 1;
  grid-row: 1 / 3;
  align-self: start;
  width: 36px;
  height: 36px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--primary-soft);
  border-radius: 8px;
}
.feature-icon .lucide {
  width: 18px;
  height: 18px;
  color: var(--primary);
  stroke-width: 2;
}

/* Title: row 1 of the text column */
.feature-card > strong,
.feature-card > .feature-body > strong,
.feature-card > .feature-body h4 {
  grid-column: 2;
  grid-row: 1;
  display: block;
  margin: 0;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--text-strong);
  line-height: 1.3;
}

/* Description: row 2 of the text column */
.feature-card > p,
.feature-card > .feature-body > p {
  grid-column: 2;
  grid-row: 2;
  margin: 0;
  font-size: 0.8rem;
  color: var(--muted);
  line-height: 1.55;
}

.feature-body h4 {
  margin: 0 0 0.3rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--text-strong);
}
.feature-body p {
  margin: 0;
  font-size: 0.8rem;
  color: var(--muted);
  line-height: 1.55;
}

/* =========================================================================
   FAQ section
   ========================================================================= */

.faq-section {
  padding: 0.95rem 1rem 1.05rem;
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 10px;
  margin-top: 1rem;
}

.faq-grid {
  display: flex;
  flex-direction: column;
  gap: 0.5rem;
  margin-top: 0.85rem;
}

.faq-card {
  border: 1px solid var(--line-soft);
  border-radius: 8px;
  background: var(--panel-alt);
  overflow: hidden;
  transition: border-color 0.15s;
}
.faq-card[open] {
  border-color: var(--primary);
}

.faq-card summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  font-size: 0.88rem;
  font-weight: 600;
  color: var(--text-strong);
  cursor: pointer;
  list-style: none;
  user-select: none;
}
.faq-card summary::-webkit-details-marker { display: none; }
.faq-card summary::after {
  content: "+";
  font-size: 1.1rem;
  font-weight: 400;
  color: var(--muted);
  flex-shrink: 0;
  transition: transform 0.15s;
}
.faq-card[open] summary::after {
  transform: rotate(45deg);
}
.faq-card summary:hover {
  color: var(--primary);
}

.faq-body {
  padding: 0 1rem 0.85rem;
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.6;
  border-top: 1px solid var(--line-soft);
  padding-top: 0.65rem;
}
.faq-body p { margin: 0 0 0.5rem; }
.faq-body p:last-child { margin-bottom: 0; }
.faq-body ol {
  margin: 0 0 0.5rem;
  padding-left: 1.15rem;
}
.faq-body li { margin-bottom: 0.3rem; }
.faq-body code {
  font-family: var(--mono);
  font-size: 0.85em;
  background: var(--panel-deep);
  border: 1px solid var(--line-soft);
  border-radius: 3px;
  padding: 0.05em 0.3em;
  color: var(--text);
}
.faq-body kbd {
  display: inline-block;
  padding: 0.1rem 0.35rem;
  border: 1px solid var(--line);
  border-radius: 4px;
  background: var(--button-bg);
  font-size: 0.82em;
  font-family: var(--mono);
}

/* =========================================================================
   How to use (in-page reference card)
   - Sits between the workspace and the "Other tools" links so users land
     on guidance the moment they scroll past the editor.
   - Each <details> is independent; collapsed by default except the first
     "Quick start" card which is open so the section communicates at-a-
     glance even before any clicks.
   - Visual rhythm matches `.other-tools` so the two stack as siblings
     (same panel border + radius + horizontal padding).
   ========================================================================= */

.how-to-use {
  padding: 0.95rem 1rem 1.05rem;
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 14px;
}

.how-to-header {
  margin-bottom: 0.7rem;
}

.how-to-header h3 {
  margin: 0;
  font-size: 0.95rem;
  color: var(--text-strong);
  letter-spacing: 0.01em;
}

.how-to-sub {
  margin: 0.15rem 0 0;
  font-size: 0.78rem;
  color: var(--muted);
}

/* Auto-fitting grid: cards collapse to a single column on narrow viewports
   and expand to 2-3 columns on wide ones. minmax() floor protects against
   text crunching on small screens; the upper bound (`1fr`) lets cards
   share remaining space evenly. */
.how-to-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 0.55rem;
}

.how-to-card {
  border: 1px solid var(--line);
  background: var(--panel-alt);
  border-radius: 10px;
  /* Reset Safari's default disclosure marker so we can render our own
     caret inside the summary. */
  overflow: hidden;
}

.how-to-card[open] {
  border-color: color-mix(in srgb, var(--primary) 35%, var(--line) 65%);
  background: color-mix(in srgb, var(--primary) 4%, var(--panel-alt) 96%);
}

/* The summary IS the clickable header. We hide the default triangle and
   draw a chevron via ::after that rotates when [open]. Keeps the
   appearance consistent across browsers and lets us use icon + label +
   meta without fighting the default marker layout. */
.how-to-card > summary {
  list-style: none;
  cursor: pointer;
  display: grid;
  /* icon | text stack | chevron */
  grid-template-columns: auto 1fr auto;
  grid-template-rows: auto auto;
  align-items: center;
  column-gap: 0.55rem;
  row-gap: 0.15rem;
  padding: 0.65rem 0.85rem;
  font-size: 0.85rem;
  color: var(--text);
  user-select: none;
}

.how-to-card > summary::-webkit-details-marker {
  display: none;
}

.how-to-card > summary::after {
  /* Lucide chevron-down rendered as a tiny svg via mask-image so it
     inherits currentColor and rotates cleanly. Falls back to a unicode
     caret in browsers without mask support. */
  content: "";
  width: 14px;
  height: 14px;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>") center / contain no-repeat;
          mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>") center / contain no-repeat;
  opacity: 0.65;
  transition: transform 120ms ease, opacity 120ms ease;
  /* Span both text rows so the chevron stays vertically centred */
  grid-column: 3;
  grid-row: 1 / 3;
  align-self: center;
  flex-shrink: 0;
}

.how-to-card[open] > summary::after {
  transform: rotate(180deg);
  opacity: 1;
}

.how-to-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 6px;
  background: color-mix(in srgb, var(--primary) 14%, transparent);
  color: var(--primary);
  /* Span both text rows so the icon stays centred regardless of wrapping */
  grid-column: 1;
  grid-row: 1 / 3;
  align-self: center;
}

.how-to-icon .lucide {
  width: 14px;
  height: 14px;
  fill: none !important;
  stroke: currentColor !important;
  stroke-width: 1.75;
}

.how-to-title {
  font-weight: 600;
  color: var(--text-strong);
  grid-column: 2;
  grid-row: 1;
  line-height: 1.3;
}

.how-to-meta {
  font-size: 0.72rem;
  color: var(--muted);
  grid-column: 2;
  grid-row: 2;
  line-height: 1.3;
}

.how-to-body {
  padding: 0.1rem 0.95rem 0.85rem;
  font-size: 0.82rem;
  line-height: 1.5;
  color: var(--text);
  border-top: 1px solid var(--line-soft);
  margin-top: 0.05rem;
  padding-top: 0.7rem;
}

.how-to-body p { margin: 0 0 0.55rem; }
.how-to-body p:last-child { margin-bottom: 0; }
.how-to-body ul,
.how-to-body ol {
  margin: 0 0 0.55rem;
  padding-left: 1.1rem;
}
.how-to-body li { margin-bottom: 0.25rem; }
.how-to-body li:last-child { margin-bottom: 0; }
.how-to-body code {
  font-family: var(--mono);
  font-size: 0.78rem;
  padding: 0.05rem 0.35rem;
  border-radius: 4px;
  background: var(--panel-deep);
  border: 1px solid var(--line-soft);
  color: var(--text-strong);
}

.how-to-body h4 {
  margin: 0.85rem 0 0.4rem;
  font-size: 0.84rem;
  font-weight: 650;
  color: var(--text-strong);
  line-height: 1.35;
}

.how-to-body h4:first-of-type {
  margin-top: 0.55rem;
}

.how-to-example-label {
  margin: 0.35rem 0 0.2rem;
  font-size: 0.78rem;
  color: var(--muted);
}

.how-to-example {
  margin: 0 0 0.55rem;
  padding: 0.55rem 0.65rem;
  overflow-x: auto;
  font-family: var(--mono);
  font-size: 0.72rem;
  line-height: 1.45;
  color: var(--text);
  background: var(--panel-deep);
  border: 1px solid var(--line-soft);
  border-radius: 6px;
  white-space: pre;
}

.how-to-example code {
  display: block;
  padding: 0;
  border: 0;
  background: transparent;
  font-size: inherit;
  color: inherit;
}

.how-to-callout {
  margin: 0.65rem 0 0;
  padding: 0.5rem 0.65rem;
  font-size: 0.78rem;
  line-height: 1.45;
  color: var(--text);
  background: color-mix(in srgb, var(--primary) 8%, var(--panel-deep));
  border: 1px solid color-mix(in srgb, var(--primary) 22%, var(--line-soft));
  border-radius: 6px;
}

.how-to-table.how-to-scenarios thead th {
  font-size: 0.74rem;
  font-weight: 600;
  color: var(--muted);
  text-align: left;
  padding-bottom: 0.35rem;
  border-bottom: 1px solid var(--line-soft);
}

.how-to-table.how-to-scenarios td {
  vertical-align: top;
  padding: 0.4rem 0.5rem 0.4rem 0;
  font-size: 0.78rem;
}

.how-to-table.how-to-scenarios td:first-child {
  white-space: nowrap;
  width: 4.5rem;
}

/* Keyboard chip — small caps-style tag readers see when scanning for
   shortcuts. We tint with --primary so the eye lands on it after
   reading the body text. */
.how-to-shortcut {
  margin-top: 0.55rem;
  font-size: 0.75rem;
  color: var(--muted);
}

.how-to-body kbd {
  display: inline-block;
  padding: 0.1rem 0.4rem;
  margin: 0 0.05rem;
  font-family: var(--mono);
  font-size: 0.72rem;
  color: var(--text-strong);
  background: var(--panel-deep);
  border: 1px solid var(--line);
  border-bottom-width: 2px;
  border-radius: 4px;
  white-space: nowrap;
}

.how-to-table {
  width: 100%;
  border-collapse: collapse;
  font-size: 0.8rem;
}

.how-to-table td {
  padding: 0.35rem 0;
  border-bottom: 1px dashed var(--line-soft);
}

.how-to-table td:first-child {
  width: 1%;
  white-space: nowrap;
  padding-right: 0.85rem;
}

.how-to-table tr:last-child td {
  border-bottom: 0;
}

/* =========================================================================
   Other tools + footer (matches existing tools)
   ========================================================================= */

.other-tools {
  padding: 0.85rem 1rem;
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 14px;
}

.other-tools h3 {
  margin: 0 0 0.6rem;
  font-size: 0.82rem;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--muted);
}

.link-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap: 0.55rem;
}

.link-grid a {
  display: block;
  padding: 0.65rem 0.8rem;
  border-radius: 10px;
  border: 1px solid var(--line);
  background: var(--panel-alt);
  color: var(--text);
  text-decoration: none;
  font-size: 0.85rem;
  transition: border-color 0.15s ease, background 0.15s ease, transform 0.15s ease;
}

.link-grid a:hover {
  border-color: var(--primary);
  background: color-mix(in srgb, var(--primary) 8%, var(--panel-alt) 92%);
  transform: translateY(-1px);
}

.page-footer {
  padding: 0.75rem 1rem;
  display: flex;
  flex-wrap: wrap;
  gap: 1rem;
  justify-content: center;
  border: 1px solid var(--line);
  background: var(--panel);
  border-radius: 12px;
  color: var(--muted);
  font-size: 0.82rem;
}

.page-footer a {
  color: var(--text);
  text-decoration: none;
  border-bottom: 1px dotted transparent;
  transition: color 0.15s ease, border-color 0.15s ease;
}

.page-footer a:hover {
  color: var(--primary);
  border-bottom-color: var(--primary);
}

/* =========================================================================
   Toast
   ========================================================================= */

.toast {
  position: fixed;
  bottom: 1.2rem;
  left: 50%;
  transform: translate(-50%, 1rem);
  background: #1f2937;
  color: #ffffff;
  padding: 0.6rem 0.95rem;
  border-radius: 10px;
  font-size: 0.85rem;
  border: 1px solid rgba(255, 255, 255, 0.1);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35);
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease, transform 0.2s ease;
  z-index: 1000;
  max-width: min(420px, 90vw);
  text-align: center;
}

.toast.is-visible {
  opacity: 1;
  transform: translate(-50%, 0);
  pointer-events: auto;
}

.toast[data-tone="error"] {
  background: #dc2626;
  color: #ffffff;
  border-color: rgba(255, 255, 255, 0.18);
}

/* =========================================================================
   Dialogs
   ========================================================================= */

.dialog {
  border: 1px solid var(--line);
  background: var(--panel);
  color: var(--text);
  border-radius: 14px;
  padding: 0;
  max-width: min(520px, 92vw);
  width: 100%;
  box-shadow: var(--shadow);
}

.dialog::backdrop {
  background: rgba(7, 13, 24, 0.55);
  backdrop-filter: blur(2px);
}

.dialog-form {
  padding: 1rem 1.1rem 1.1rem;
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
}

.dialog-form h3 {
  margin: 0;
  color: var(--text-strong);
  font-size: 1rem;
}

.dialog-hint {
  margin: 0;
  font-size: 0.8rem;
  color: var(--muted);
}

.text-input,
.text-area {
  width: 100%;
  border: 1px solid var(--line);
  background: var(--panel-deep);
  color: var(--text);
  border-radius: 8px;
  padding: 0.55rem 0.7rem;
  font-size: 0.88rem;
  font-family: inherit;
}

.text-area {
  font-family: var(--mono);
  resize: vertical;
  min-height: 160px;
}

.text-input:focus,
.text-area:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--primary-soft);
}

.dialog-actions {
  display: flex;
  justify-content: flex-end;
  gap: 0.5rem;
}

/* =========================================================================
   JSONEditor theming overrides (match panels in both themes)
   ========================================================================= */

.tree-host .jsoneditor {
  border: 0;
  height: 100%;
  background: var(--tree-bg);
  color: var(--text);
}

.tree-host .jsoneditor-menu {
  background: var(--pane-header-bg);
  border-bottom: 1px solid var(--line-soft);
}

.tree-host .jsoneditor-tree,
.tree-host .jsoneditor-outer,
.tree-host .jsoneditor table.jsoneditor-tree {
  background: var(--tree-bg);
  color: var(--text);
}

.tree-host div.jsoneditor-field,
.tree-host div.jsoneditor-value {
  color: var(--text);
}

/* JSON value colors: matched to Monaco vs-dark / vs syntax highlighting so
   the tree view reads like the same JSON the formatted/minified Monaco shows. */
.tree-host div.jsoneditor-field { color: #9cdcfe; }
.tree-host div.jsoneditor-value.jsoneditor-string  { color: #ce9178; }
.tree-host div.jsoneditor-value.jsoneditor-number  { color: #b5cea8; }
.tree-host div.jsoneditor-value.jsoneditor-boolean { color: #569cd6; }
.tree-host div.jsoneditor-value.jsoneditor-null    { color: #569cd6; font-style: italic; }

[data-theme="light"] .tree-host div.jsoneditor-field { color: #001080; }
[data-theme="light"] .tree-host div.jsoneditor-value.jsoneditor-string  { color: #a31515; }
[data-theme="light"] .tree-host div.jsoneditor-value.jsoneditor-number  { color: #098658; }
[data-theme="light"] .tree-host div.jsoneditor-value.jsoneditor-boolean { color: #0000ff; }
[data-theme="light"] .tree-host div.jsoneditor-value.jsoneditor-null    { color: #0000ff; font-style: italic; }

.tree-host div.jsoneditor-field[contenteditable="true"]:focus,
.tree-host div.jsoneditor-value[contenteditable="true"]:focus,
.tree-host div.jsoneditor-field[contenteditable="true"]:hover,
.tree-host div.jsoneditor-value[contenteditable="true"]:hover {
  background: var(--primary-soft);
  border-color: var(--primary);
  outline: none;
}

.tree-host div.jsoneditor-search {
  background: var(--panel-alt);
  border: 1px solid var(--line);
  border-radius: 8px;
}

.tree-host .jsoneditor-popover,
.tree-host .jsoneditor-treepath,
.tree-host .jsoneditor-search input {
  background: var(--panel-alt);
  color: var(--text);
}

/* Custom context menu row added in tree.js (no sprite slot in JSONEditor). */
.tree-host button.jsoneditor-copy .jsoneditor-icon {
  background-image: none;
  background-color: var(--text);
  opacity: 0.85;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill='%23fff' d='M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z'/%3E%3C/svg%3E");
  -webkit-mask-size: 16px 16px;
  mask-size: 16px 16px;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
}

[data-theme="light"] .tree-host button.jsoneditor-copy .jsoneditor-icon {
  opacity: 0.75;
}

/* =========================================================================
   Responsive
   ========================================================================= */

@media (max-width: 1100px) {
  /* Sidebar is already horizontal — just hide labels on medium screens */
  .side-btn-label {
    display: none;
  }

  .side-btn {
    justify-content: center;
    padding: 0.42rem 0.5rem;
  }

  .badge-soon {
    display: none;
  }
}


@media (max-width: 820px) {
  .topbar {
    gap: 0.6rem;
  }

  .topbar-tools {
    width: 100%;
    justify-content: flex-start;
  }

  .search-box {
    flex: 1 1 100%;
    min-width: 0;
  }

  .badge-soon {
    display: none;
  }

  .split-shell {
    min-height: clamp(260px, calc(100dvh - 16rem), 720px);
    height: auto;
    grid-template-rows: minmax(0, 1fr) auto minmax(0, 1fr);
    grid-template-columns: 1fr;
  }

  .split-shell[data-diff-mode="true"] {
    /* Only two visible items (splitter + output) when input pane is hidden,
       so the row template has only two tracks too. See the desktop rule
       above for the full explanation. */
    grid-template-rows: auto minmax(0, 1fr);
    grid-template-columns: 1fr;
  }

  .split-shell .pane + .pane {
    border-left: 0;
    border-top: 1px solid var(--line);
  }

  /* Horizontal rail on small screens */
  .splitter {
    cursor: row-resize;
    border-left: 0;
    border-right: 0;
    border-top: 1px solid var(--line);
    border-bottom: 1px solid var(--line);
    padding: 0.4rem 0.6rem;
    overflow: hidden;
  }

  .splitter-rail {
    flex-direction: row;
    justify-content: flex-start;
    gap: 0.5rem;
    overflow-x: auto;
    overflow-y: hidden;
    scrollbar-width: none;
    -webkit-overflow-scrolling: touch;
    width: 100%;
    padding-bottom: 1px; /* prevent clip on focus ring */
  }

  .splitter-rail::-webkit-scrollbar {
    display: none;
  }

  .splitter-btn {
    flex-direction: row;
    flex-shrink: 0;
    width: auto;
    min-height: 36px;
    padding: 0.4rem 0.7rem;
  }

  .splitter-icon {
    font-size: 0.85rem;
  }

  .splitter-label {
    font-size: 0.78rem;
  }
}

@media (max-width: 540px) {
  .app-shell {
    padding: 0.5rem;
    gap: 0.5rem;
  }

  .topbar {
    padding: 0.6rem 0.7rem;
  }

  h1 {
    font-size: 0.95rem;
  }

  /* On phones the tagline + chip would otherwise crowd the top bar.
     Allow the chip to wrap onto its own line and shrink the chip text
     so the trust signal stays visible without forcing a horizontal
     scroll on narrow viewports. */
  .tagline {
    font-size: 0.74rem;
  }
  .privacy-chip {
    font-size: 0.66rem;
    padding: 0.22rem 0.45rem;
    white-space: normal;
  }

  .splitter-btn {
    padding: 0.35rem 0.55rem;
    min-height: 32px;
    font-size: 0.74rem;
  }

  .splitter-icon {
    display: none;
  }

  .btn {
    padding: 0.45rem 0.6rem;
    font-size: 0.8rem;
  }

  .search-box {
    padding: 0.15rem 0.3rem;
  }

  .search-input {
    font-size: 0.8rem;
  }

  .pane-output.is-fullscreen .pane-overlay-tr,
  .pane-output.is-fullscreen .pane-overlay-tl {
    top: clamp(0.32rem, 0.22rem + 1.1vw, 0.55rem);
  }

  .pane-output.is-fullscreen .pane-overlay-tl {
    left: clamp(0.42rem, 0.35rem + 1.4vw, 1rem);
  }

  .pane-output.is-fullscreen .pane-overlay-tr {
    right: clamp(0.42rem, 0.35rem + 1.4vw, 1rem);
  }

  /* Fullscreen tree: a bit more rail for wrapped icon rows + slightly narrower search cap. */
  .pane-output.is-fullscreen[data-mode="tree"] {
    --fs-tree-tl-right: clamp(3.75rem, 2rem + 15vw, 7.25rem);
  }

  .pane-output.is-fullscreen[data-mode="tree"] .fs-search-bar {
    width: min(
      clamp(10rem, 44vw + 3.5rem, 17rem),
      calc(100% - clamp(5.25rem, 16vw + 2rem, 9rem))
    );
  }

  .pane-overlay-tl,
  .pane-overlay-tr {
    top: 0.35rem;
  }

  .pane-overlay-tl { left: 0.45rem; }
  .pane-overlay-tr { right: 0.55rem; }

  .pane-chip {
    font-size: 0.6rem;
    padding: 0.15rem 0.45rem;
  }

  .overlay-btn {
    width: 24px;
    height: 24px;
  }

  .overlay-btn svg {
    width: 13px;
    height: 13px;
  }

  .statusbar {
    padding: 0.22rem 0.65rem;
    font-size: 0.72rem;
  }

  .other-tools {
    padding: 0.7rem;
  }

  .how-to-use {
    padding: 0.75rem;
  }
  /* On the smallest screens, drop to a single-column layout so each
     card has full width to breathe — the auto-fit grid would otherwise
     leave a single oversized card centered. */
  .how-to-grid {
    grid-template-columns: 1fr;
  }
  .how-to-card > summary .how-to-meta {
    /* Hide the subtitle on tiny screens to save vertical space */
    display: none;
  }
}
