/* ============================================================
   Worksheet Designer — v2 design (loaded AFTER style.css to override).
   Scoped under .worksheet-v2 so other pages are unaffected.
   ============================================================ */

/* Grid colour vars live at :root so JS can override them from
   document.documentElement and have the change inherit down to every cell.
   Previously these were nested inside `.worksheet-v2 { ... }`, which made
   <body> (which has class="worksheet-v2") re-declare them — shadowing any
   inline override set on <html> and breaking the user's Grid color picker. */
:root {
  --grid-border: rgba(173, 125, 55, 0.55);
  --grid-guide:  rgba(173, 125, 55, 0.45);
}

.worksheet-v2 {
  --ws-ink:        #2d2823;
  --ws-ink-soft:   #4c4138;
  --ws-mute:       #7b7167;
  --ws-faint:      #9a8e82;
  --ws-border:     rgba(118, 96, 70, 0.13);
  --ws-border-hi:  rgba(118, 96, 70, 0.26);
  --ws-surface:    rgba(255, 252, 246, 0.78);
  --ws-surface-hi: rgba(255, 252, 246, 0.92);
  --ws-paper:      rgba(255, 255, 255, 0.86);
  --ws-cream:      #f5ebd9;
  --ws-cream-soft: #f8f0df;
  --ws-green:      #143c2a;
  --ws-green-hi:   #1d5238;
  --ws-gold:       #ad7d37;
  --ws-red:        #a64630;
  --ws-shadow-1:   0 1px 2px rgba(72, 54, 31, 0.03);
  --ws-shadow-2:   0 14px 36px -10px rgba(72, 54, 31, 0.10);
  --ws-shadow-3:   0 24px 60px -16px rgba(72, 54, 31, 0.14);

  background:
    radial-gradient(circle at 15% 78%, rgba(196, 168, 115, 0.16), transparent 28%),
    radial-gradient(circle at 88% 16%, rgba(148, 168, 134, 0.18), transparent 30%),
    linear-gradient(135deg, #fbf8f0 0%, #f8f2e7 48%, #fbfaf6 100%);
  color: var(--ws-ink);
  min-height: 100vh;
  font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
}

/* ── Site header (override) ──────────────────────────────── */
.worksheet-v2 .site-header {
  background: rgba(255, 252, 246, 0.78);
  backdrop-filter: saturate(180%) blur(18px);
  -webkit-backdrop-filter: saturate(180%) blur(18px);
  border-bottom: 1px solid var(--ws-border);
}
.worksheet-v2 .header-inner {
  max-width: 1440px; margin: 0 auto;
  padding: 0.85rem 1.75rem;
  display: flex; align-items: center; gap: 1.5rem;
}
.worksheet-v2 .brand {
  display: inline-flex; align-items: center; gap: 0.75rem;
  text-decoration: none; margin-right: auto;
}
.worksheet-v2 .brand-logo {
  height: 80px; width: auto; display: block;
}
.worksheet-v2 .brand-name {
  font-size: 1rem; font-weight: 700;
  color: var(--ws-ink); letter-spacing: -0.005em;
  white-space: nowrap;
}

.worksheet-v2 .site-nav-links {
  display: flex; align-items: center; gap: 0.4rem;
  margin: 0 auto;
}
.worksheet-v2 .nav-link {
  padding: 0.55rem 1.1rem;
  border-radius: 999px;
  font-size: 0.86rem; font-weight: 500;
  color: var(--ws-ink-soft);
  text-decoration: none;
  letter-spacing: 0.005em;
  transition: background 0.18s ease, color 0.18s ease;
}
.worksheet-v2 .nav-link:hover  { background: rgba(118, 96, 70, 0.06); color: var(--ws-ink); }
.worksheet-v2 .nav-link.active {
  background: var(--ws-green); color: #f7f1e8;
  box-shadow: 0 6px 16px -4px rgba(20, 60, 42, 0.30);
}

/* ── Page wrapper ────────────────────────────────────────── */
.worksheet-v2 .ws-page {
  max-width: 1440px;
  margin: 0 auto;
  padding: 2rem 1.75rem 4rem;
}

/* ── Hero / title area ───────────────────────────────────── */
.worksheet-v2 .ws-hero {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 2rem;
  align-items: end;
  margin-bottom: 1.85rem;
  padding: 0 0.25rem;
}
.worksheet-v2 .ws-eyebrow {
  display: inline-block;
  font-size: 0.72rem; font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ws-gold);
  margin-bottom: 0.7rem;
}
.worksheet-v2 .ws-title {
  font-family: Georgia, 'Times New Roman', 'STSong', serif;
  font-size: clamp(1.8rem, 3.4vw, 2.7rem);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -0.025em;
  color: var(--ws-ink);
  margin: 0;
  max-width: 760px;
}
.worksheet-v2 .ws-hero-cn {
  font-size: 0.92rem;
  color: var(--ws-mute);
  line-height: 1.7;
  margin: 0;
  max-width: 320px;
  text-align: right;
}

/* ── 3-column grid ───────────────────────────────────────── */
.worksheet-v2 .ws-grid {
  display: grid;
  grid-template-columns: minmax(280px, 320px) minmax(0, 1fr) minmax(280px, 340px);
  gap: 1.2rem;
  align-items: start;
}
.worksheet-v2 .ws-col {
  display: flex; flex-direction: column; gap: 1rem;
  min-width: 0;
}

/* ── Generic card ────────────────────────────────────────── */
.worksheet-v2 .ws-card {
  background: var(--ws-surface-hi);
  border: 1px solid var(--ws-border);
  border-radius: 18px;
  padding: 1.05rem 1.15rem 1.05rem;
  box-shadow: var(--ws-shadow-1), var(--ws-shadow-2);
  display: flex; flex-direction: column; gap: 0.65rem;
}
.worksheet-v2 .ws-card-head {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.5rem;
  font: inherit; color: inherit; background: none; border: none; padding: 0;
  text-align: left;
}
.worksheet-v2 .ws-card-title {
  font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ws-ink-soft);
}
.worksheet-v2 .ws-card-tag {
  font-size: 0.72rem;
  color: var(--ws-faint);
  font-weight: 500;
  letter-spacing: 0.02em;
}
.worksheet-v2 .ws-card-foot {
  display: flex; align-items: center; justify-content: space-between;
  gap: 0.5rem; margin-top: 0.1rem;
}
/* Characters card: card body acts as an extended click target that
   focuses the textarea, with a text-cursor for affordance. */
.worksheet-v2 .ws-card-textarea { cursor: text; }
.worksheet-v2 .ws-card-textarea .ws-card-head,
.worksheet-v2 .ws-card-textarea .ws-card-foot,
.worksheet-v2 .ws-card-textarea .ws-link,
.worksheet-v2 .ws-card-textarea .input-actions { cursor: default; }
.worksheet-v2 .ws-card-textarea .ws-textarea { cursor: text; }
.worksheet-v2 .ws-card-hint {
  font-size: 0.72rem; color: var(--ws-faint);
}

/* Generate Sheet CTA inside the Characters card — full-width primary
   action that lives directly below the hint / Del / Clear row. */
.worksheet-v2 .ws-card-cta {
  width: 100%;
  justify-content: center;
  margin-top: 0.65rem;
}

/* ── Characters textarea ────────────────────────────────── */
.worksheet-v2 .ws-textarea {
  width: 100%;
  min-height: 140px;
  resize: vertical;
  padding: 0.8rem 0.95rem;
  font-family: 'Kaiti SC', 'STKaiti', 'KaiTi', '楷体', serif;
  font-size: 1.05rem;
  line-height: 1.5;
  color: var(--ws-ink);
  background: rgba(255, 255, 255, 0.6);
  border: 1px solid var(--ws-border);
  border-radius: 12px;
  outline: none;
  transition: border-color 0.18s ease, box-shadow 0.18s ease, background 0.18s ease;
  letter-spacing: 0.04em;
}
.worksheet-v2 .ws-textarea::placeholder {
  font-family: Inter, -apple-system, sans-serif;
  font-size: 0.9rem;
  color: var(--ws-faint);
  letter-spacing: 0;
}
.worksheet-v2 .ws-textarea:focus {
  border-color: var(--ws-green);
  box-shadow: 0 0 0 4px rgba(20, 60, 42, 0.08);
  background: #fff;
}

.worksheet-v2 .ws-link {
  border: none; background: none;
  font: inherit; cursor: pointer;
  padding: 0.2rem 0.45rem; border-radius: 6px;
  font-size: 0.78rem; color: var(--ws-mute);
  transition: background 0.15s, color 0.15s;
}
.worksheet-v2 .ws-link:hover { background: rgba(118, 96, 70, 0.08); color: var(--ws-ink); }
.worksheet-v2 .ws-link-danger { color: var(--ws-red); }
.worksheet-v2 .ws-link-danger:hover { background: rgba(166, 70, 48, 0.10); color: #7d2f1f; }

/* ── Sheet type tiles ───────────────────────────────────── */
.worksheet-v2 .ws-sheet-types {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 0.55rem;
  background: none; border: none; padding: 0;
  border-radius: 0;
}
.worksheet-v2 .ws-sheet-tile {
  display: flex; flex-direction: column; align-items: center;
  gap: 0.4rem;
  padding: 0.85rem 0.6rem 0.75rem;
  background: rgba(255, 255, 255, 0.55);
  border: 1.5px solid var(--ws-border);
  border-radius: 14px;
  cursor: pointer;
  font-family: inherit; color: var(--ws-ink-soft);
  font-size: 0.82rem;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease, transform 0.08s ease, box-shadow 0.18s ease;
}
.worksheet-v2 .ws-sheet-tile:hover {
  background: rgba(255, 255, 255, 0.85);
  border-color: var(--ws-border-hi);
  transform: translateY(-1px);
}
.worksheet-v2 .ws-sheet-tile.active {
  background: var(--ws-green); color: #f7f1e8;
  border-color: var(--ws-green);
  box-shadow: 0 10px 24px -6px rgba(20, 60, 42, 0.32);
}
.worksheet-v2 .ws-sheet-glyph {
  font-family: 'Kaiti SC', 'STKaiti', 'KaiTi', '楷体', serif;
  font-size: 1.55rem; font-weight: 600;
  line-height: 1;
}
.worksheet-v2 .ws-sheet-name {
  font-size: 0.78rem; font-weight: 600;
  letter-spacing: 0.02em;
}

/* ── Collapsible panels (Components / Stroke Sheet) ─────── */
.worksheet-v2 .cmp-panel-header,
.worksheet-v2 .stroke-panel-header {
  cursor: pointer;
  width: 100%; padding: 0;
  background: none; border: none;
}
.worksheet-v2 .cmp-panel-body,
.worksheet-v2 .stroke-content {
  margin-top: 0.55rem;
}
.worksheet-v2 .stroke-group-label {
  font-size: 0.7rem; font-weight: 600;
  letter-spacing: 0.06em; text-transform: uppercase;
  color: var(--ws-mute);
  margin: 0.4rem 0 0.4rem;
}

/* ── Center column: preview bar + paper ─────────────────── */
.worksheet-v2 .ws-preview-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
  padding: 0.85rem 1.1rem;
  background: var(--ws-surface-hi);
  border: 1px solid var(--ws-border);
  border-radius: 16px;
  box-shadow: var(--ws-shadow-1), var(--ws-shadow-2);
  margin-bottom: 0.9rem;
}
.worksheet-v2 .ws-preview-status {
  display: flex; align-items: center; gap: 0.7rem;
  min-width: 0;
}
.worksheet-v2 .ws-status-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background: var(--ws-green);
  box-shadow: 0 0 0 4px rgba(20, 60, 42, 0.12);
  flex-shrink: 0;
}
.worksheet-v2 .ws-status-title {
  font-size: 0.95rem; font-weight: 600;
  color: var(--ws-ink); letter-spacing: -0.005em;
}
.worksheet-v2 .ws-status-sub {
  font-size: 0.76rem; color: var(--ws-mute);
  margin-top: 0.1rem;
}
.worksheet-v2 .ws-preview-actions {
  display: flex; align-items: center; gap: 0.45rem;
}

/* Buttons */
.worksheet-v2 .ws-btn {
  display: inline-flex; align-items: center; gap: 0.4rem;
  padding: 0.55rem 1rem;
  border-radius: 11px;
  font-family: inherit;
  font-size: 0.85rem; font-weight: 600;
  letter-spacing: 0.005em;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease, transform 0.08s ease, box-shadow 0.18s ease;
}
.worksheet-v2 .ws-btn:active { transform: scale(0.97); }
.worksheet-v2 .ws-btn-primary {
  background: var(--ws-green); color: #f7f1e8;
  box-shadow: 0 8px 20px -4px rgba(20, 60, 42, 0.30);
}
.worksheet-v2 .ws-btn-primary:hover {
  background: var(--ws-green-hi);
  box-shadow: 0 10px 24px -4px rgba(20, 60, 42, 0.38);
}
.worksheet-v2 .ws-btn-ghost {
  background: rgba(255, 255, 255, 0.7);
  border-color: var(--ws-border);
  color: var(--ws-ink);
}
.worksheet-v2 .ws-btn-ghost:hover {
  background: rgba(255, 255, 255, 0.95);
  border-color: var(--ws-border-hi);
}
.worksheet-v2 .ws-btn-icon { padding: 0.55rem 0.85rem; }

/* Override the preview page card to match the new aesthetic */
.worksheet-v2 .copybook-wrap   { background: transparent; padding: 0; }
.worksheet-v2 .preview-page {
  background: var(--ws-paper);
  border: 1px solid var(--ws-border);
  border-radius: 16px;
  box-shadow: var(--ws-shadow-1), var(--ws-shadow-3);
  /* Fixed A4 shape on screen so the page number pins to the bottom and every
     page reads as a complete sheet. paintPagedSheet() measures against this
     box and tops the remainder up with blank practice blocks. */
  aspect-ratio: 210 / 297;
  overflow: hidden;
}
.worksheet-v2 .preview-content {
  flex: 1 1 auto; min-height: 0;
  display: flex; flex-direction: column;
  overflow: hidden;
}
.worksheet-v2 .preview-page-num { flex-shrink: 0; }

/* ── Blank-page print dialog ─────────────────────────────── */
.worksheet-v2 .ws-modal-backdrop {
  position: fixed; inset: 0; z-index: 1200;
  display: none; align-items: center; justify-content: center;
  padding: 1.25rem;
  background: rgba(45, 40, 35, 0.5);
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
}
.worksheet-v2 .ws-modal-backdrop.open { display: flex; }
.worksheet-v2 .ws-modal-card {
  position: relative;
  width: 100%; max-width: 380px;
  background: var(--ws-surface-hi);
  border: 1px solid var(--ws-border);
  border-radius: 18px;
  box-shadow: 0 26px 60px -16px rgba(72, 54, 31, 0.34);
  padding: 1.5rem 1.5rem 1.25rem;
  color: var(--ws-ink);
}
.worksheet-v2 .ws-modal-close {
  position: absolute; top: 0.55rem; right: 0.7rem;
  width: 30px; height: 30px; border: none; background: none;
  font-size: 1.5rem; line-height: 1; color: var(--ws-mute);
  cursor: pointer; border-radius: 8px;
}
.worksheet-v2 .ws-modal-close:hover { background: rgba(20, 60, 42, 0.07); color: var(--ws-ink); }
.worksheet-v2 .ws-modal-title {
  font-family: Georgia, 'Times New Roman', 'STSong', serif;
  font-size: 1.2rem; font-weight: 600; color: var(--ws-ink);
  margin: 0 1.5rem 0.5rem 0; letter-spacing: -0.01em;
}
.worksheet-v2 .ws-modal-sub {
  font-size: 0.88rem; color: var(--ws-mute); line-height: 1.55;
  margin: 0 0 1.1rem;
}
.worksheet-v2 .ws-modal-field {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; margin-bottom: 0.9rem;
}
.worksheet-v2 .ws-modal-field label {
  font-size: 0.9rem; font-weight: 600; color: var(--ws-ink-soft);
}
.worksheet-v2 .ws-modal-field input[type="number"] {
  width: 90px; padding: 0.5rem 0.6rem;
  border: 1px solid var(--ws-border-hi); border-radius: 10px;
  font: inherit; font-size: 0.95rem; color: var(--ws-ink);
  background: #fffefa; text-align: center;
}
.worksheet-v2 .ws-modal-field input[type="number"]:focus {
  outline: none; border-color: var(--ws-green);
  box-shadow: 0 0 0 3px rgba(20, 60, 42, 0.12);
}
.worksheet-v2 .ws-modal-check {
  display: flex; align-items: center; gap: 0.55rem;
  font-size: 0.9rem; color: var(--ws-ink-soft);
  cursor: pointer; margin-bottom: 1.25rem;
}
.worksheet-v2 .ws-modal-check input {
  width: 16px; height: 16px; accent-color: var(--ws-green); cursor: pointer;
}
.worksheet-v2 .ws-modal-actions {
  display: flex; justify-content: flex-end; gap: 0.6rem;
}
.worksheet-v2 .ws-modal-btn {
  padding: 0.55rem 1.15rem; border-radius: 999px;
  font: inherit; font-size: 0.88rem; font-weight: 600;
  cursor: pointer; border: 1px solid transparent;
  transition: background 0.15s ease, border-color 0.15s ease, color 0.15s ease;
}
.worksheet-v2 .ws-modal-btn.ghost {
  background: transparent; border-color: var(--ws-border-hi); color: var(--ws-ink-soft);
}
.worksheet-v2 .ws-modal-btn.ghost:hover { background: rgba(255, 255, 255, 0.9); color: var(--ws-ink); }
.worksheet-v2 .ws-modal-btn.primary {
  background: var(--ws-green); color: #f7f1e8;
  box-shadow: 0 8px 18px -4px rgba(20, 60, 42, 0.34);
}
.worksheet-v2 .ws-modal-btn.primary:hover { background: var(--ws-green-hi); }
@media print { .worksheet-v2 .ws-modal-backdrop { display: none !important; } }

/* ── Right column: Grid Style tiles ─────────────────────── */
.worksheet-v2 .ws-grid-styles {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 0.5rem;
}
.worksheet-v2 .ws-grid-tile {
  display: flex; flex-direction: column; align-items: center;
  gap: 0.5rem;
  padding: 0.7rem 0.5rem 0.6rem;
  background: rgba(255, 255, 255, 0.55);
  border: 1.5px solid var(--ws-border);
  border-radius: 12px;
  cursor: pointer;
  font-family: inherit; color: var(--ws-ink-soft);
  transition: background 0.18s ease, border-color 0.18s ease, color 0.18s ease, transform 0.08s ease;
}
.worksheet-v2 .ws-grid-tile:hover {
  background: rgba(255, 255, 255, 0.85);
  border-color: var(--ws-border-hi);
  transform: translateY(-1px);
}
.worksheet-v2 .ws-grid-tile.active {
  background: rgba(20, 60, 42, 0.06);
  border-color: var(--ws-green);
  color: var(--ws-green);
  box-shadow: 0 1px 2px rgba(20, 60, 42, 0.05);
}
.worksheet-v2 .ws-grid-name {
  font-family: 'Kaiti SC', 'STKaiti', 'KaiTi', '楷体', serif;
  font-size: 0.78rem; font-weight: 600;
  letter-spacing: 0.05em;
}
/* Mini grid previews — SVG backgrounds match the actual cell rendering
   exactly (same stroke color, dash pattern, opacity). overflow: hidden
   clips anything that would otherwise spill past the rounded corners. */
.worksheet-v2 .ws-grid-mini {
  position: relative;
  width: 36px; height: 36px;
  border-radius: 6px;
  background-color: rgba(255, 255, 255, 0.8);
  border: 1px solid rgba(173, 125, 55, 0.55);
  overflow: hidden;
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
/* 田字格 — dashed cross */
.worksheet-v2 .ws-grid-mini-tianzi {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cg stroke='%23b38a4c' stroke-width='2.5' stroke-dasharray='4,3' opacity='0.85'%3E%3Cline x1='50' y1='0' x2='50' y2='100'/%3E%3Cline x1='0' y1='50' x2='100' y2='50'/%3E%3C/g%3E%3C/svg%3E");
}
/* 米字格 — dashed cross + dashed diagonals */
.worksheet-v2 .ws-grid-mini-mizi {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cg stroke='%23b38a4c' stroke-width='2.5' stroke-dasharray='4,3' opacity='0.85'%3E%3Cline x1='50' y1='0' x2='50' y2='100'/%3E%3Cline x1='0' y1='50' x2='100' y2='50'/%3E%3Cline x1='0' y1='0' x2='100' y2='100'/%3E%3Cline x1='100' y1='0' x2='0' y2='100'/%3E%3C/g%3E%3C/svg%3E");
}
/* 十字格 — solid cross only */
.worksheet-v2 .ws-grid-mini-shizi {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cg stroke='%23b38a4c' stroke-width='2.5' opacity='0.85'%3E%3Cline x1='50' y1='0' x2='50' y2='100'/%3E%3Cline x1='0' y1='50' x2='100' y2='50'/%3E%3C/g%3E%3C/svg%3E");
}
/* 方格 — nothing inside, just the border */
.worksheet-v2 .ws-grid-mini-fang { /* empty interior */ }

/* ── Layout slider ──────────────────────────────────────── */
.worksheet-v2 .ws-control {
  display: flex; align-items: center; gap: 0.85rem;
  margin-top: 0.2rem;
}
.worksheet-v2 .ws-control-spacer { margin-top: 0.85rem; }
.worksheet-v2 .ws-range {
  flex: 1;
  appearance: none; -webkit-appearance: none;
  height: 4px; border-radius: 4px;
  background: rgba(20, 60, 42, 0.14);
  cursor: pointer;
  accent-color: var(--ws-green);
}
.worksheet-v2 .ws-range::-webkit-slider-thumb {
  -webkit-appearance: none;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--ws-green);
  cursor: pointer;
  box-shadow: 0 2px 6px rgba(20, 60, 42, 0.30);
}
.worksheet-v2 .ws-range::-moz-range-thumb {
  width: 16px; height: 16px; border: none; border-radius: 50%;
  background: var(--ws-green); cursor: pointer;
  box-shadow: 0 2px 6px rgba(20, 60, 42, 0.30);
}
.worksheet-v2 .ws-range-val {
  font-variant-numeric: tabular-nums;
  font-weight: 700; font-size: 0.85rem;
  color: var(--ws-ink);
  min-width: 2.4em; text-align: right;
}
.worksheet-v2 .ws-range-labels {
  display: flex; justify-content: space-between;
  font-size: 0.7rem; color: var(--ws-faint);
  letter-spacing: 0.01em;
  margin-top: 0.35rem;
}

/* ── Section sub-labels (e.g. "Ink color" / "Grid color") ──── */
.worksheet-v2 .ws-sublabel {
  font-size: 0.72rem; font-weight: 700;
  color: var(--ws-muted, #7b7167);
  letter-spacing: 0.06em; text-transform: uppercase;
  margin: 0 0 0.5rem;
}
.worksheet-v2 .ws-sublabel-spaced { margin-top: 0.85rem; }

/* ── Color swatches ─────────────────────────────────────── */
.worksheet-v2 .ws-colors {
  display: flex; flex-wrap: wrap; gap: 0.45rem;
  padding: 0.15rem 0;
}
.worksheet-v2 .ws-color,
.worksheet-v2 .ws-colors .color-swatch {
  width: 24px; height: 24px;
  border-radius: 50%;
  border: 2px solid #fff;
  cursor: pointer;
  padding: 0;
  box-shadow:
    0 0 0 1px rgba(24, 24, 27, 0.10),
    0 1px 2px rgba(24, 24, 27, 0.06);
  transition: transform 0.15s cubic-bezier(.2,.8,.2,1), box-shadow 0.18s ease;
}
.worksheet-v2 .ws-color:hover,
.worksheet-v2 .ws-colors .color-swatch:hover {
  transform: scale(1.15) translateY(-1px);
  box-shadow:
    0 0 0 1.5px var(--ws-green),
    0 4px 10px -2px rgba(24, 24, 27, 0.18);
}
.worksheet-v2 .ws-color.active,
.worksheet-v2 .ws-colors .color-swatch.active {
  box-shadow:
    0 0 0 2px #fff,
    0 0 0 4px var(--ws-ink);
}

/* ── Select dropdown ────────────────────────────────────── */
.worksheet-v2 .ws-select {
  appearance: none; -webkit-appearance: none; -moz-appearance: none;
  width: 100%;
  padding: 0.65rem 2.2rem 0.65rem 0.85rem;
  border: 1px solid var(--ws-border);
  border-radius: 12px;
  background-color: rgba(255, 255, 255, 0.7);
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%237b7167' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
  background-repeat: no-repeat;
  background-position: right 0.85rem center;
  color: var(--ws-ink);
  font-family: 'Kaiti SC', 'STKaiti', 'KaiTi', '楷体', inherit;
  font-size: 0.92rem;
  cursor: pointer;
  outline: none;
  transition: border-color 0.18s ease, box-shadow 0.18s ease;
  margin-top: 0.55rem;
}
.worksheet-v2 .ws-select:hover { border-color: var(--ws-border-hi); }
.worksheet-v2 .ws-select:focus {
  border-color: var(--ws-green);
  box-shadow: 0 0 0 4px rgba(20, 60, 42, 0.08);
}

/* ── Toggle switches ────────────────────────────────────── */
.worksheet-v2 .ws-toggle {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem;
  padding: 0.35rem 0;
  font-size: 0.88rem;
  color: var(--ws-ink);
  cursor: pointer;
}
.worksheet-v2 .ws-switch {
  appearance: none; -webkit-appearance: none;
  position: relative;
  width: 38px; height: 22px;
  border-radius: 999px;
  background: rgba(118, 96, 70, 0.18);
  cursor: pointer;
  transition: background 0.2s ease;
  flex-shrink: 0;
  margin: 0;
}
.worksheet-v2 .ws-switch::after {
  content: '';
  position: absolute;
  top: 2px; left: 2px;
  width: 18px; height: 18px;
  background: #fff;
  border-radius: 50%;
  box-shadow: 0 1px 3px rgba(24, 24, 27, 0.18);
  transition: transform 0.22s cubic-bezier(.2,.8,.2,1);
}
.worksheet-v2 .ws-switch:checked        { background: var(--ws-green); }
.worksheet-v2 .ws-switch:checked::after { transform: translateX(16px); }

/* ── Footer ─────────────────────────────────────────────── */
.worksheet-v2 .ws-footer {
  border-top: 1px solid var(--ws-border);
  margin-top: 3rem;
  background: transparent;
  color: var(--ws-faint);
  text-align: center;
  padding: 1.2rem 1rem 1.5rem;
}
.worksheet-v2 .ws-footer a {
  color: var(--ws-gold); text-decoration: none;
  border-bottom: 1px dashed currentColor;
}
.worksheet-v2 .ws-footer .site-footer-sep { color: var(--ws-border-hi); margin: 0 0.5em; }

/* ── Grid style variants (the actual rendered cells) ────── */
/* Override .tian-cell::before depending on data-grid attribute on #copybook */

/* 田字格 (default) — dashed cross. Inherits the existing style.css rule;
   we re-state it here so it applies even after our overrides. */
.worksheet-v2[data-grid="tianzi"] .tian-cell::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image:
    repeating-linear-gradient(90deg, var(--grid-guide) 0px, var(--grid-guide) 3px, transparent 3px, transparent 7px),
    repeating-linear-gradient(0deg,  var(--grid-guide) 0px, var(--grid-guide) 3px, transparent 3px, transparent 7px);
  background-size:     100% 1px, 1px 100%;
  background-position: 0 50%,    50% 0;
  background-repeat:   repeat-x, repeat-y;
}
/* 米字格 — cross + dashed diagonals. CSS gradients can't easily draw a
   thin diagonal band, so we use an inline SVG (4 dashed lines) stretched
   to fill the cell. opacity dropped to 0.45 so the inner guides sit
   visually behind the 0.55 outer cell borders. */
.worksheet-v2[data-grid="mizi"] .tian-cell::before {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cg stroke='%23b38a4c' stroke-width='0.9' stroke-dasharray='2.5,2.5' opacity='0.45'%3E%3Cline x1='50' y1='0' x2='50' y2='100'/%3E%3Cline x1='0' y1='50' x2='100' y2='50'/%3E%3Cline x1='0' y1='0' x2='100' y2='100'/%3E%3Cline x1='100' y1='0' x2='0' y2='100'/%3E%3C/g%3E%3C/svg%3E");
  background-size: 100% 100%;
  background-repeat: no-repeat;
}
/* 十字格 — exactly ONE solid horizontal middle line + ONE solid
   vertical middle line. Two background-image layers explicitly sized
   to a 1px band each and centered, no repeat. No calc tricks, no
   auto-sized gradients, no shorthand resets — same skeleton as the
   田字格 default rule so the result is impossible to misrender:

       ┌───┬───┐
       │   │   │       (two lines forming one cross,
       ├───┼───┤        dividing the cell into 2×2 quadrants)
       │   │   │
       └───┴───┘
*/
.worksheet-v2[data-grid="shizi"] .tian-cell::before {
  content: '';
  position: absolute; inset: 0;
  pointer-events: none;
  background-color: transparent;
  background-image:
    linear-gradient(rgba(173, 125, 55, 0.30), rgba(173, 125, 55, 0.30)),
    linear-gradient(rgba(173, 125, 55, 0.30), rgba(173, 125, 55, 0.30));
  background-size:     100% 1px, 1px 100%;
  background-position: center;
  background-repeat:   no-repeat;
}
/* 方格 — plain square, no internal guides */
.worksheet-v2[data-grid="fang"] .tian-cell::before {
  content: none;
}

/* Cell borders themselves: keep the existing solid outer borders for tianzi/
   mizi/shizi; soften slightly for the warmer palette. 方格 keeps borders too.
   Use the same CSS variable as the base .tian-cell border rule so the user's
   Grid color picker actually takes effect here (the more-specific selector
   would otherwise lock the colour). */
.worksheet-v2 .tian-cell {
  border-color: var(--grid-border);
}

/* ── Hide elements present for legacy compatibility ─────── */
.worksheet-v2 #blank-minus[hidden],
.worksheet-v2 #blank-plus[hidden] { display: none !important; }

/* The old .stepper isn't used anymore in v2 but might appear if other CSS sets it */
.worksheet-v2 .stepper { display: none; }

/* ── Responsive ─────────────────────────────────────────── */
@media (max-width: 1200px) {
  .worksheet-v2 .ws-grid {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.6fr);
  }
  .worksheet-v2 .ws-col-right {
    grid-column: 1 / -1;
    flex-direction: row; flex-wrap: wrap;
  }
  .worksheet-v2 .ws-col-right .ws-card { flex: 1 1 280px; }
}
@media (max-width: 820px) {
  .worksheet-v2 .ws-page { padding: 1.25rem 1rem 2.5rem; }
  .worksheet-v2 .ws-hero { grid-template-columns: 1fr; gap: 0.75rem; align-items: start; }
  .worksheet-v2 .ws-hero-cn { text-align: left; max-width: 100%; }
  .worksheet-v2 .ws-grid { grid-template-columns: 1fr; }
  .worksheet-v2 .ws-col-right { flex-direction: column; }
  .worksheet-v2 .ws-col-right .ws-card { flex: unset; }

  /* Header: brand + auth stay on row 1, nav links wrap to a centered row 2 */
  .worksheet-v2 .header-inner { padding: 0.7rem 1rem; gap: 0.6rem 0.75rem; flex-wrap: wrap; }
  .worksheet-v2 .brand-logo { height: 56px; }
  .worksheet-v2 .site-nav-links {
    order: 3; flex-basis: 100%; margin: 0;
    justify-content: center; flex-wrap: wrap; gap: 0.3rem 0.4rem;
  }
  .worksheet-v2 .nav-link { padding: 0.45rem 0.85rem; font-size: 0.82rem; white-space: nowrap; }
}

@media (max-width: 480px) {
  .worksheet-v2 .ws-page { padding: 1rem 0.8rem 2.5rem; }
  .worksheet-v2 .brand-logo { height: 48px; }
  /* Preview action bar: let the primary button fill the row */
  .worksheet-v2 .ws-preview-actions { width: 100%; }
  .worksheet-v2 .ws-preview-actions .ws-btn-primary { flex: 1 1 auto; justify-content: center; }
}

/* ── Row spacing & pinyin practice lines ───────────────────
   Two independent layers, both driven off <body> attributes / vars:

   • Row Spacing slider sets `--row-gap` (mm) and toggles `data-has-gap`.
     CSS uses these to add margin-bottom on each row, frame the gap
     with left/right borders, and re-instate the top border on the
     row that follows the gap (so cells don't look decapitated).

   • Pinyin Lines toggle sets `data-pinyin-lines="on"`. CSS paints the
     standard 拼音四线三格 (4 horizontal guides) into the existing gap.
     The toggle on its own does NOT create gap — the slider's job.
     (The inline script auto-pumps the slider to 12 mm when the user
      turns lines on while gap is 0, so users still get the expected
      one-click behavior.)
   ────────────────────────────────────────────────────────── */
.worksheet-v2[data-has-gap] .char-row {
  position: relative;
  margin-bottom: var(--row-gap);
  /* Each row provides its OWN left edge so the gap area between rows
     stays pure whitespace. (The grid's border-left would otherwise
     cut through the gap as a residual vertical line on the left.) */
  border-left: 1px solid var(--grid-border);
  box-sizing: border-box;
}
.worksheet-v2[data-has-gap] .char-row + .char-row {
  border-top: 1px solid var(--grid-border);
}
/* With per-row left borders, suppress the grid-level left border so we
   don't double up (which would also draw the missing strip across the
   gap area). The grid's top border still provides the worksheet's top
   edge above the very first row. */
.worksheet-v2[data-has-gap] .copybook-grid,
.worksheet-v2[data-has-gap] .preview-page .copybook-grid {
  border-left: 0 !important;
}
.worksheet-v2[data-has-gap] .char-row::after {
  content: '';
  position: absolute;
  left: 0; right: 0; top: 100%;
  height: var(--row-gap);
  /* Gap area is PURE whitespace by default — each row stays visually
     independent. Only the Pinyin Lines mode below restores left/right
     borders (because the 4-line pattern needs a bounded region to read
     as a stave). */
  box-sizing: border-box;
  pointer-events: none;
}
/* The last row in each grid has nothing beneath it — drop its trailing
   margin (and the ::after stub) for a clean bottom edge. */
.worksheet-v2[data-has-gap] .char-row:last-child {
  margin-bottom: 0;
}
.worksheet-v2[data-has-gap] .char-row:last-child::after {
  display: none;
}
/* Hanzi mode renders each character as its own .char-block with one grid,
   so the .char-row above is ALWAYS :last-child and the per-row --row-gap
   margin gets nulled. Drive inter-block margin from the slider directly
   (replacing the style.css 10mm default) so:
     • slider = 0mm → 0 gap, rows truly tight (stroke-order row gives natural
       visual separation)
     • slider = 20mm → 20mm gap, generous spacing
   The whole range is the slider's, with no hidden additive baseline. */
.worksheet-v2 .preview-page .char-block + .char-block {
  margin-top: var(--row-gap, 0mm);
}
/* When Pinyin Lines is ON, every .char-block already contains a real
   .pinyin-stave element above its grid, sized to var(--row-gap) and painting
   the 4-line stave. Zero the inter-block margin so we don't stack a margin
   AND a stave (which would double the visible gap). The stave alone carries
   the user's slider value as the visible spacing. */
.worksheet-v2[data-pinyin-lines="on"] .preview-page .char-block + .char-block {
  margin-top: 0;
}
.worksheet-v2[data-has-gap][data-pinyin-lines="on"] .char-row::after {
  background-image:
    /* upper guide (1/3) — dashed */
    repeating-linear-gradient(to right,
      rgba(173, 125, 55, 0.40) 0, rgba(173, 125, 55, 0.40) 5px,
      transparent 5px, transparent 9px),
    /* lower guide (2/3, baseline) — dashed */
    repeating-linear-gradient(to right,
      rgba(173, 125, 55, 0.40) 0, rgba(173, 125, 55, 0.40) 5px,
      transparent 5px, transparent 9px);
  background-size: 100% 1px;
  background-position: 0 33.33%, 0 66.66%;
  background-repeat: no-repeat;
}
/* On a blank sheet the gap staves only sit BELOW each row, so the very first
   row would have no pinyin guide above it. We add a REAL stave element above
   the first row (a normal block in flow — it can never overlap or cut into the
   cells, unlike an absolutely-positioned pseudo). It only takes up space and
   shows its guide lines in Pinyin Lines mode; otherwise it collapses away. */
.worksheet-v2 .pinyin-stave { display: none; }
.worksheet-v2[data-has-gap][data-pinyin-lines="on"] .pinyin-stave {
  display: block;
  height: var(--row-gap);
  pointer-events: none;
  background-image:
    /* upper guide (1/3) — dashed */
    repeating-linear-gradient(to right,
      rgba(173, 125, 55, 0.40) 0, rgba(173, 125, 55, 0.40) 5px,
      transparent 5px, transparent 9px),
    /* lower guide (2/3, baseline) — dashed */
    repeating-linear-gradient(to right,
      rgba(173, 125, 55, 0.40) 0, rgba(173, 125, 55, 0.40) 5px,
      transparent 5px, transparent 9px);
  background-size: 100% 1px;
  background-position: 0 33.33%, 0 66.66%;
  background-repeat: no-repeat;
}

/* ── Print ─────────────────────────────────────────────────
   Hide every wrapper added by the v2 layout (header, hero,
   side columns, preview-bar, footer, modals) so only the
   actual practice sheet inside #copybook prints. The existing
   .preview-page / .tian-cell print rules in style.css still
   apply because those class names are preserved by script.js.
   ────────────────────────────────────────────────────────── */
@media print {
  .worksheet-v2 {
    background: #ffffff !important;
  }
  .worksheet-v2 .site-header,
  .worksheet-v2 .ws-hero,
  .worksheet-v2 .ws-col-left,
  .worksheet-v2 .ws-col-right,
  .worksheet-v2 .ws-preview-bar,
  .worksheet-v2 .ws-footer,
  .worksheet-v2 .modal-backdrop,
  .worksheet-v2 .nav-auth { display: none !important; }

  /* Print mirror of the screen rule: slider value IS the inter-block margin
     (replacing the style.css 8mm print default), so slider = 0 prints tight. */
  .worksheet-v2 .preview-page .char-block + .char-block {
    margin-top: var(--row-gap, 0mm);
  }
  /* Same Pinyin Lines de-doubling rule for print. */
  .worksheet-v2[data-pinyin-lines="on"] .preview-page .char-block + .char-block {
    margin-top: 0;
  }

  /* Crisp pinyin guides in print. The on-screen lines are drawn with
     background-image gradients, which rasterize fuzzy (and sometimes ghost
     into a double line) at print resolution. Redraw them here as VECTOR dashed
     borders — two lines centered at ~1/3 and ~2/3 of the gap, matching screen.
     Both the first-row stave and the between-row gap (::after) get the same. */
  .worksheet-v2[data-has-gap][data-pinyin-lines="on"] .pinyin-stave {
    background: none !important;
    box-sizing: border-box !important;
    height: calc(var(--row-gap) * 0.34) !important;
    margin: calc(var(--row-gap) * 0.33) 0 !important;
    border-top:    0.75pt dashed rgba(173, 125, 55, 0.65) !important;
    border-bottom: 0.75pt dashed rgba(173, 125, 55, 0.65) !important;
  }
  .worksheet-v2[data-has-gap][data-pinyin-lines="on"] .char-row::after {
    background: none !important;
    box-sizing: border-box !important;
    top: calc(100% + var(--row-gap) * 0.33) !important;
    height: calc(var(--row-gap) * 0.34) !important;
    border-top:    0.75pt dashed rgba(173, 125, 55, 0.65) !important;
    border-bottom: 0.75pt dashed rgba(173, 125, 55, 0.65) !important;
  }
  .worksheet-v2[data-has-gap] .char-row:last-child::after { display: none !important; }

  .worksheet-v2 .ws-page {
    padding: 0 !important;
    margin:  0 !important;
    max-width: none !important;
  }
  .worksheet-v2 .ws-grid {
    display: block !important;
    gap: 0 !important;
  }
  .worksheet-v2 .ws-col-center {
    display: block !important;
    width: 100% !important;
  }
  /* The cards in the center column are JUST the preview area now —
     strip their warm-paper styling so the sheet sits on plain white. */
  .worksheet-v2 .ws-col-center .ws-card,
  .worksheet-v2 .copybook-wrap {
    background: #ffffff !important;
    border: none !important;
    box-shadow: none !important;
    padding: 0 !important;
    margin: 0 !important;
    border-radius: 0 !important;
  }

  /* ── Print pagination: natural flow, fill every sheet ──────
     The on-screen preview is built as fixed-height A4-ratio page boxes (good
     for screen). In PRINT those boxes don't match the printer's real A4 area,
     so forcing one box per sheet (break-after) left big bottom whitespace and
     broke early. Instead collapse the page boxes to plain block flow and let
     the browser paginate to fill each physical sheet; the break-inside rules
     below stop any block/row being cut across a page boundary. */
  .worksheet-v2 .copybook-wrap { display: block !important; }
  .worksheet-v2 .preview-page {
    display: block !important;
    height: auto !important; aspect-ratio: auto !important; overflow: visible !important;
    break-after: auto !important;  page-break-after: auto !important;
    break-inside: auto !important; page-break-inside: auto !important;
  }
  .worksheet-v2 .preview-content { display: block !important; overflow: visible !important; }
  /* Keep uniform spacing across the (now-invisible) screen-page boundaries so
     blocks don't touch where one on-screen page's content meets the next. */
  .worksheet-v2 .preview-page + .preview-page { margin-top: 8mm !important; }
  /* Natural-flow browser print can't place a per-sheet "Page X / N" footer
     (CSS @page margin boxes aren't supported by browsers), so hide the
     on-screen footers when printing. The live preview keeps them. */
  .worksheet-v2 .preview-page-num { display: none !important; }

  /* ── Blank practice pages (from the "Print blank pages" dialog) ──
     These are explicitly one-page-per-sheet, so opt them OUT of natural flow:
     force a page break after each and keep each whole, so page N+1's grid never
     bleeds onto page N. Each page's row count is an A4-ratio fill, which always
     fits within one printable A4 — so no clipping or overflow. Their page-number
     footer is one-per-sheet here, so keep it visible. */
  .worksheet-v2 .preview-page.print-blank-page {
    break-after: page !important;  page-break-after: always !important;
    break-inside: avoid !important; page-break-inside: avoid !important;
  }
  .worksheet-v2 .preview-page.print-blank-page:last-child {
    break-after: auto !important;  page-break-after: auto !important;
  }
  .worksheet-v2 .preview-page.print-blank-page .preview-page-num { display: block !important; }

  /* Keep heads intact and rows whole, but let a tall block flow row-by-row:
       • the head (annotation/seq + its first traced row) stays together;
       • a single practice row is never split in half;
       • a tall block (many blank rows) breaks BETWEEN whole rows, not mid-row. */
  .worksheet-v2 .preview-page .char-block { break-inside: auto !important; page-break-inside: auto !important; }
  .worksheet-v2 .char-row { break-inside: avoid; page-break-inside: avoid; }
  .worksheet-v2 .char-seq-row,
  .worksheet-v2 .stroke-name-row,
  .worksheet-v2 .comp-block-header,
  .worksheet-v2 .pinyin-stave { break-after: avoid; page-break-after: avoid; }

  /* ── Grid-style print overrides ────────────────────────
     style.css has a print rule for .preview-page .tian-cell::before
     that paints the 田字格 dashed cross unconditionally. We need to
     fully override its background-* properties (not just background-
     image), otherwise position/repeat values leak through and produce
     stray lines or wrong placement. Hence the explicit !important
     reset of every background property per grid style. */

  /* All four grid styles use inline SVG in print (more reliable than CSS
     gradients at print resolution, and unified line color: warm gold to
     match cell borders). Stroke widths and dash patterns are tuned to
     survive browser rasterization without merging into solid lines. */

  /* 田字格 — dashed cross */
  .worksheet-v2[data-grid="tianzi"] .preview-page .tian-cell::before {
    content: '' !important;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cg stroke='%23b38a4c' stroke-opacity='0.55' stroke-width='1' stroke-dasharray='6,5'%3E%3Cline x1='50' y1='0' x2='50' y2='100'/%3E%3Cline x1='0' y1='50' x2='100' y2='50'/%3E%3C/g%3E%3C/svg%3E") !important;
    background-size:     100% 100% !important;
    background-position: 0 0 !important;
    background-repeat:   no-repeat !important;
  }

  /* 米字格 — dashed cross + dashed diagonals.
     Intrinsic 200x200 forces the UA to rasterize the SVG at higher
     resolution; stroke-width 1.5 keeps strokes super-pixel; dasharray
     5 4 (and applied per-<line>, not via <g> inheritance) survives
     anti-aliasing on the 45° diagonals. opacity 0.45 keeps the inner
     guides visually subordinate to the 0.55 outer cell borders. */
  .worksheet-v2[data-grid="mizi"] .preview-page .tian-cell::before {
    content: '' !important;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cg stroke='%23b38a4c' stroke-opacity='0.45' stroke-width='1.5' fill='none'%3E%3Cline x1='50' y1='0' x2='50' y2='100' stroke-dasharray='5 4'/%3E%3Cline x1='0' y1='50' x2='100' y2='50' stroke-dasharray='5 4'/%3E%3Cline x1='0' y1='0' x2='100' y2='100' stroke-dasharray='5 4'/%3E%3Cline x1='100' y1='0' x2='0' y2='100' stroke-dasharray='5 4'/%3E%3C/g%3E%3C/svg%3E") !important;
    background-size:     100% 100% !important;
    background-position: 0 0 !important;
    background-repeat:   no-repeat !important;
  }

  /* 十字格 — solid cross only. Thin stroke (0.5 in a 100-viewBox)
     and 0.20 opacity to keep the cross as a faint guide; the outer
     cell borders should dominate visually. */
  .worksheet-v2[data-grid="shizi"] .preview-page .tian-cell::before {
    content: '' !important;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100' preserveAspectRatio='none'%3E%3Cg stroke='%23b38a4c' stroke-opacity='0.22' stroke-width='0.5'%3E%3Cline x1='50' y1='0' x2='50' y2='100'/%3E%3Cline x1='0' y1='50' x2='100' y2='50'/%3E%3C/g%3E%3C/svg%3E") !important;
    background-size:     100% 100% !important;
    background-position: 0 0 !important;
    background-repeat:   no-repeat !important;
  }

  /* 方格 — no inner guides at all */
  .worksheet-v2[data-grid="fang"] .preview-page .tian-cell::before {
    content:    none !important;
    background: none !important;
  }
}

/* ============================================================
   Free-tier watermark — only visible when printing / saving to PDF
   ============================================================ */
.mw-watermark { display: none; }
.mw-watermark.print-only { display: none; }

@media print {
  .mw-watermark.print-only {
    display: block !important;
    position: fixed;
    bottom: 8mm;
    right: 10mm;
    font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
    font-size: 9pt;
    color: #6b6b6b;
    letter-spacing: 0.02em;
    z-index: 9999;
    pointer-events: none;
    /* Lift it above the page background but stay visually quiet */
    background: rgba(255, 255, 255, 0.65);
    padding: 2pt 6pt;
    border-radius: 4pt;
    -webkit-print-color-adjust: exact !important;
    print-color-adjust: exact !important;
  }
}

/* (The empty preview now uses the same row-gap behavior as a real
   worksheet — every .char-row owns its left edge, so gap areas stay
   pure whitespace whether or not the user has typed anything. The
   `.ws-empty-preview` class on <preview-page> is kept as a marker for
   future tweaks, but needs no special CSS today.) */
