/* 07-settings-site.css — part 07/10 of the ordered bp bundle (the former single bp.css,
   split by surface; the content is UNREORDERED). ORDER IS LOAD-BEARING: cascade ties
   resolve by document order, so hosts must link 01→10 in exactly this sequence —
   CssHygieneTests pins both the list and the order in both hosts. */

/* ── /settings hub form tabs (rp-set*, wave 5 Task 7 — Настройки.dc.html, П-20) ─────────────────
   Signup / cancellation / video settings forms. Native HTML on tokens (no MudBlazor); the desktop
   card is a 600px column, the mobile view (≤640px) collapses the two-column grid to one and stretches
   the submit full-width — one markup tree, CSS-only responsive switch. */
.rp-set { max-width: 600px; }
.rp-set-loading { display: flex; justify-content: center; padding: 32px; }

.rp-set-introrow { display: flex; align-items: center; gap: 12px; margin-bottom: 16px; }
.rp-set-intro {
  flex: 1;
  min-width: 0;
  font-size: 13px;
  color: var(--muted-foreground);
  line-height: 1.6;
  margin: 0 0 16px;
}
.rp-set-introrow .rp-set-intro { margin: 0; }
.rp-set-sitelink {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 34px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--card);
  color: var(--foreground);
  font-size: 12.5px;
  font-weight: 600;
  text-decoration: none;
}
.rp-set-sitelink:hover { background: var(--accent); }

.rp-set-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--card);
  padding: 20px;
}

/* switch row — bespoke 38×22 pill switch (П-9; the mockup size matches no BbSwitch/prior preset) */
.rp-set-switchrow { display: flex; align-items: flex-start; gap: 12px; margin-bottom: 16px; }
.rp-set-switchrow--dim { opacity: 0.45; }
/* .rp-set-switch geometry is in the canonical toggle block (global controls section); only the row
   alignment nudge, disabled state and a11y focus ring are component-specific. */
.rp-set-switch { margin-top: 1px; }
.rp-set-switch:disabled { cursor: not-allowed; }
.rp-set-switch:focus-visible { outline: 2px solid var(--ring); outline-offset: 2px; }
.rp-set-switchtext { min-width: 0; }
.rp-set-switch-label { font-size: 13.5px; font-weight: 600; }
.rp-set-switch-cap { font-size: 12.5px; color: var(--muted-foreground); line-height: 1.5; }

/* field grid + inputs */
.rp-set-grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 16px; }
.rp-set-field { display: block; }
.rp-set-field--minage { max-width: 240px; margin-bottom: 18px; }
.rp-set-field--dim { opacity: 0.45; }
.rp-set-label { display: block; font-size: 12.5px; font-weight: 600; margin-bottom: 5px; }
.rp-set-input {
  height: 42px;
  font: inherit;
  font-size: 13.5px;
}
select.rp-set-input { padding: 0 10px; cursor: pointer; }
.rp-set-hint { display: block; font-size: 11.5px; color: var(--muted-foreground); margin-top: 4px; }

.rp-set-err {
  font-size: 12.5px;
  color: var(--destructive);
  margin-bottom: 12px;
}

@media (max-width: 640px) {
  .rp-set-grid2 { grid-template-columns: 1fr; }
  .rp-set-field--minage { max-width: none; }
  .rp-set-card .rp-btn-submit { width: 100%; height: 44px; }
}

/* ── «ИИ-функции» tab (rp-set-aicard / rp-set-infocard, wave 5 Task 8 — Настройки.dc.html) ────────── */
.rp-set-aicard { margin-bottom: 14px; }
.rp-set-field--voice { max-width: 262px; margin-bottom: 16px; }

.rp-set-infocard {
  display: flex;
  align-items: center;
  gap: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--card);
  padding: 16px 20px;
}
.rp-set-infocard-text { flex: 1; min-width: 0; }
.rp-set-infocard-title { font-size: 13.5px; font-weight: 600; }
.rp-set-infocard-cap { font-size: 12.5px; color: var(--muted-foreground); line-height: 1.5; }
.rp-set-infocard-chip { flex-shrink: 0; }

/* ── «Площадка» tab: tenant card + destructive close zone (rp-set-tenant* / rp-set-danger*) ────────── */
.rp-set-tenantcard {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--card);
  padding: 20px;
  margin-bottom: 14px;
}
.rp-set-tenant-name { font-size: 14.5px; font-weight: 700; margin-bottom: 4px; }
.rp-set-tenant-host { font-size: 13px; color: var(--muted-foreground); }

.rp-set-danger {
  border: 1px solid color-mix(in srgb, var(--destructive) 35%, var(--border));
  border-radius: var(--radius-lg);
  background: var(--card);
  padding: 20px;
}
.rp-set-danger-title { font-size: 14.5px; font-weight: 700; color: var(--destructive); margin-bottom: 10px; }
.rp-set-danger-warn {
  border: 1px solid color-mix(in srgb, var(--destructive) 25%, var(--border));
  background: color-mix(in srgb, var(--destructive) 6%, var(--card));
  border-radius: var(--radius-md);
  padding: 13px 16px;
  margin-bottom: 16px;
  font-size: 12.5px;
  line-height: 1.6;
}
.rp-set-danger-warn-title { font-size: 12.5px; font-weight: 700; margin-bottom: 6px; }
.rp-set-danger-list { margin: 0; padding-left: 18px; font-size: 12.5px; line-height: 1.7; color: var(--muted-foreground); }
.rp-set-danger-note { font-size: 12.5px; margin-top: 8px; }
.rp-set-danger-lead { font-size: 13px; color: var(--muted-foreground); margin: 0 0 10px; }

.rp-set-danger-row { display: flex; gap: 8px; align-items: flex-end; }
.rp-set-danger-field { flex: 1; }
.rp-set-danger-fullfield { display: block; margin-bottom: 12px; }
.rp-set-danger-actions { display: flex; gap: 12px; align-items: center; flex-wrap: wrap; }

/* destructive buttons — 38px tall, tokens only */
.rp-btn-danger,
.rp-btn-danger-outline {
  height: 38px;
  padding: 0 16px;
  border-radius: var(--radius-md);
  font: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
}
.rp-btn-danger { border: 0; background: var(--destructive); color: var(--destructive-foreground); }
.rp-btn-danger-outline { border: 1px solid var(--destructive); background: transparent; color: var(--destructive); }
.rp-btn-danger:disabled,
.rp-btn-danger-outline:disabled { opacity: 0.6; cursor: not-allowed; }

.rp-btn-textlink {
  border: 0;
  background: transparent;
  color: var(--muted-foreground);
  font: inherit;
  font-size: 13px;
  cursor: pointer;
  padding: 0 4px;
  /* Пользовательская жалоба (аудит 2026-08-21): без подчёркивания текстовая кнопка неотличима от
     описания рядом. Полупрозрачная линия в статике, полная на hover; currentColor держит обе темы. */
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-color: color-mix(in srgb, currentColor 55%, transparent);
}
.rp-btn-textlink:hover { color: var(--foreground); text-decoration-color: currentColor; }
.rp-btn-textlink:disabled { opacity: 0.6; cursor: not-allowed; }

@media (max-width: 640px) {
  .rp-set-danger-row { flex-direction: column; align-items: stretch; }
  .rp-set-danger-row .rp-btn-danger-outline { width: 100%; height: 44px; }
  .rp-set-danger-actions .rp-btn-danger,
  .rp-set-danger-actions .rp-btn-submit { width: 100%; height: 44px; }
  .rp-set-danger .rp-btn-submit { width: 100%; height: 44px; }
}

/* ── «Мой сайт» hub — template/colour picker (wave 5 Task 9, Мой сайт.dc.html; folded into the header's
   «Цвет и вид» popover by my-site-redesign Task 17 — SiteThemePopover, own rules further below in the
   rp-site2* / rp-site-pop* block). Cabinet CHROME (template/colour cards) uses var(--…) cabinet
   tokens so it flips with dark mode. The wave-5 tab's own controls column (.rp-site, a single narrow
   420px column) and its always-visible section headers (.rp-site-group-title) went with the deleted
   SiteAppearancePanel — the popover's own headers are .rp-site-pop-title. .rp-site-tpl*, .rp-site-color*
   and .rp-site-hexfield survive (the popover renders them, colour swatches now 46px per the Task 17
   handoff, up from the tab's smaller 34/38px — no longer viewport-scaled, since the popover itself is a
   fixed 380px regardless of screen width). SP4 drops .rp-site-topbtn/.rp-site-loading — SitePage's own
   top-action links moved to rp-site2-btn back in Task 13 (see rp-site2* above), so their only remaining
   consumer was the now-deleted domain panel's Pro-gate upsell. */

.rp-site-hexfield { max-width: 200px; margin-top: 8px; }

/* Template cards */
.rp-site-templates { display: grid; gap: 10px; margin-bottom: 22px; }
.rp-site-tpl {
  display: flex; align-items: center; gap: 12px; text-align: left;
  border: 1.5px solid var(--border); border-radius: var(--radius-lg);
  background: var(--card); padding: 10px 12px; cursor: pointer; font: inherit;
}
.rp-site-tpl:hover { border-color: color-mix(in srgb, var(--primary) 50%, var(--border)); }
.rp-site-tpl--active { border-color: var(--primary); }
.rp-site-tpl-thumb {
  width: 64px; height: 46px; flex-shrink: 0;
  border: 1px solid var(--border); border-radius: var(--radius-sm);
  padding: 6px; display: flex; flex-direction: column; gap: 4px;
}
.rp-site-tpl-bar { width: 80%; height: 6px; border-radius: 2px; }
.rp-site-tpl-sub { width: 60%; height: 3px; border-radius: 2px; background: var(--border); }
.rp-site-tpl-text { flex: 1; min-width: 0; }
.rp-site-tpl-name {
  display: flex; align-items: center; gap: 6px;
  font-size: 13px; font-weight: 600; color: var(--foreground);
}
.rp-site-tpl-name svg { color: var(--primary); }
.rp-site-tpl-desc {
  display: block; font-size: 11.5px; color: var(--muted-foreground); line-height: 1.4; margin-top: 2px;
}

/* Colour presets — 46px swatches (Task 17 handoff). */
.rp-site-colors { display: flex; align-items: center; gap: 9px; margin-bottom: 8px; }
.rp-site-color {
  width: 46px; height: 46px; border-radius: 50%;
  border: 2.5px solid transparent; cursor: pointer;
  box-shadow: 0 0 0 2px var(--card) inset;
}
.rp-site-color--active { border-color: var(--foreground); }

/* Содержание tab: the REAL shared blocks (Repetitum.Landing.Blocks) reference cabinet tokens for
   their card/border/muted colours and inline var(--tpl-font-*) for headings, so remapping the tokens
   here re-skins them with no per-block edits. Scoped to .rp-land-preview (the inner preview) — the
   editing chrome stays cabinet-themed. .rp-site-footer-preview (Task 15) gets the SAME remap for the
   site-footer plaque, under its own class name rather than rp-land-preview — see that wrapper's own
   doc comment for why (a hidden-strip test needs .rp-land-preview to be absent when the only rendered
   block is collapsed). */
.rp-land-preview.rp-tpl-scope[data-template],
.rp-site-footer-preview.rp-tpl-scope[data-template] {
  --card: var(--tpl-card-surface);
  --foreground: var(--tpl-ink);
  --muted-foreground: var(--tpl-muted);
  --border: var(--tpl-line);
  background: var(--tpl-surface);
  font-family: var(--tpl-font-body);
  /* Remapping the VARIABLES is not enough: `color` inherits by computed value, so anything
     relying on inheritance (RpInlineText/RpInlineArea are `color: inherit`) picked up the
     CABINET theme's foreground — light-on-white in dark mode, dark-on-dark for vivid in light
     mode. Restart inheritance from the template's own ink at the scope boundary. */
  color: var(--tpl-ink);
}

/* ── Landing-block surface (wave 5 Task 10, rp-land*; the old edit-dialog arm was removed by the
   inline-WYSIWYG-editor task set, Task 9) ───────────────────────────────────────────────────
   Shared chrome for LandingPreviewSurface (Мой сайт §Содержание + онбординг превью) — the preview
   cards edit in place now. Structure/tokens only; the accent icon colour is applied inline. */
.rp-land-intro {
  font-size: 13px; color: var(--muted-foreground); line-height: 1.6; margin: 0 0 16px;
}

.rp-land-block {
  position: relative;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--card); padding: 14px 18px; margin-bottom: 10px;
}
/* A hidden block dims its CONTENT preview only — never the whole card: the frame carries the
   hide/show button and the rp-land-offwarn strips, and CSS opacity multiplies down the tree, so a
   card-level 0.55 would grey out the very warnings that exist to be noticed. */
.rp-land-block--off > .rp-land-preview { opacity: 0.55; }

/* Idle state (Task 14 — click-to-edit): the block IS the editor's read view, cursor:pointer + a
   dashed hover outline invite the click, and the always-visible pencil chip anchors that intent for
   an audience that does not reliably discover hover affordances. */
.rp-land-block.rp-site-block--idle { cursor: pointer; }
.rp-land-block.rp-site-block--idle:hover {
  outline: 2px dashed var(--primary); outline-offset: -2px;
}
/* Touch has no hover — a stuck dashed outline after a tap would look like a rendering bug, not an
   affordance, so coarse pointers keep the pencil chip only (mirrors CourseStructureTree's probe). */
.rp-land-block.rp-site-block--coarse:hover { outline: none; }

/* Spec §2.3 item 3 (fix round 1, Important): the OPEN block keeps a permanent solid outline — every
   `.rp-land-block` without the idle class IS the one currently open (see the render loop: isOpen ?
   "" : IdleClass), so this selector never needs an explicit "open" class of its own. */
.rp-land-block:not(.rp-site-block--idle) {
  outline: 2px solid var(--primary); outline-offset: -2px;
}

/* rp-site-pencil is a real <button> (fix round 1, Important — a bare aria-hidden span left the idle
   block with zero focusable elements, a keyboard regression from the chrome it replaced). Click
   bubbles to the block's own @onclick (OpenBlock is idempotent), and native <button> Enter/Space
   dispatches that same bubbling click, so no separate keydown handler is needed. */
.rp-site-pencil {
  position: absolute; top: 10px; right: 10px; z-index: 1;
  width: 36px; height: 36px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--card); border: 1px solid var(--border); box-shadow: var(--shadow-xs);
  color: var(--muted-foreground); cursor: pointer;
}
.rp-site-pencil:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* SP3, «Мой сайт - редизайн.dc.html» §3a: 32px on touch. The chip is the block's ONLY affordance there
   (the dashed hover outline right above is suppressed on a coarse pointer), and on a phone-width card
   it sits over the block's own preview — the handoff trades 4px of chip for that overlap. */
.rp-land-block.rp-site-block--coarse .rp-site-pencil { width: 32px; height: 32px; }

/* rp-site-hidden-strip (Task 15) — the FULL hidden-block treatment: a disabled, unopened block
   collapses to this strip instead of drawing a dimmed preview, replacing Task 14's smaller
   rp-land-hidden-tag badge (removed — nothing emits it any more) with a words-first row that also
   carries the one-click way back to visible. */
.rp-site-hidden-strip {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 2px; color: var(--muted-foreground);
}
.rp-site-hidden-text { flex: 1; min-width: 0; font-size: 13.5px; }
.rp-site-hidden-btn {
  flex-shrink: 0; height: 34px; padding: 0 14px;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--card); color: var(--foreground);
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.rp-site-hidden-btn:hover { border-color: var(--primary); color: var(--primary); }

/* rp-site-auto-plaque (Task 15) — the tariffs/schedule «Заполняется само из «…»» pill: floats just
   above the block card's own top-right corner (the card is already position:relative — rp-land-block).
   The --footer variant sits inline, above the site footer instead of overlapping a card. */
.rp-site-auto-plaque {
  position: absolute; top: -12px; right: 40px; z-index: 2;
  display: inline-flex; align-items: center; gap: 4px;
  padding: 4px 12px; border-radius: 999px; font-size: 11.5px; font-weight: 600;
  background: var(--muted); color: var(--muted-foreground); border: 1px solid var(--border);
  text-decoration: none; white-space: nowrap;
}
.rp-site-auto-plaque:hover { color: var(--primary); border-color: var(--primary); }
.rp-site-auto-plaque--footer {
  position: static; display: inline-flex; margin-bottom: 10px;
}

@media (max-width: 640px) {
  /* Task 6 — 44px hit-target audit, measured with a standalone repro (real bp.css + the
     blazorblueprint.css preflight, real tokens.css, Playwright getBoundingClientRect at 375px —
     reading the cascade alone is how earlier rounds of this same audit missed a collapsed element,
     e.g. .rp-siteaddr-addrow's flex-basis trap further down this file). Both the collapsed-block
     «Показать» button and the auto-block plaque link render well under the 44px floor on a touch
     screen (34px / ~27px measured) — fine with a mouse pointer's precise hit, not fine for a
     finger. Height only, and only at this breakpoint: the desktop badge/pill sizing is unchanged.
     This is the WIDTH half of the fix — a coarse pointer on a wide screen needs the pointer-keyed
     twin further down (`.rp-site-block--coarse`), since it never crosses this breakpoint. */
  .rp-site-hidden-btn { height: 44px; }
  .rp-site-auto-plaque { min-height: 44px; }
  /* Review finding: .rp-site-auto-plaque is position:absolute/top:-12px, so growing its height
     stretches it DOWNWARD — and the collapsed, DEFAULT state of a platform block (tariffs/schedule
     ship DefaultEnabled:false) renders the plaque directly above the hidden-strip's own text, with
     none of the 80px+ of headroom an OPEN block's real preview content has above it. Measured on a
     standalone repro reproducing that exact collapsed-block DOM (rp-land-block--off +
     rp-site-auto-plaque + rp-site-hidden-strip together, 375px): before the 44px floor above, the
     plaque's bottom sat 4.75px above the strip's text; after, the taller plaque's bottom overlapped
     the text by 12px. Pushing the plaque itself further up would just as easily run it into the
     PRECEDING block (only 10px of margin between cards) — pushing the strip's own content down
     instead is the fix that costs nothing else: it re-opens a >0 gap (measured 6px at 375px, wider
     at 640px) without moving the plaque, and only applies at this breakpoint, where the plaque is
     actually taller than before. */
  .rp-site-hidden-strip { margin-top: 18px; }
}

/* Task 6, review round 2 — the POINTER half of the same fix: a coarse pointer on a WIDE screen (a
   landscape tablet, ~1024px) never crosses the ≤640px query above, so the pair stayed at its old
   34px/~27px there — the same class of gap the switch fix (rp-sitemob-switch, further down this
   file) closed for MobileEditorShell, on the one surface where MobileEditorShell's own JS gate
   doesn't apply (this feed renders unconditionally, for a real desktop mouse user too, so the raise
   can't simply go unconditional the way the switch's did). `.rp-site-block--coarse` is the existing,
   width-independent signal for exactly this: an IDLE block wrapper carries it whenever
   `_coarsePointer` is true (`LandingPreviewSurface.IdleClass` — the class travels with the idle
   modifier, so the OPEN block does not have it; on a coarse pointer that block is being edited in
   MobileEditorShell anyway, which owns its own sizes), already used above to shrink
   `.rp-site-pencil` on touch. Re-declaring the SAME
   three rules (height/min-height/margin-top) under this selector — not swapping the width query out
   for it — closes the pointer axis without touching the width axis or a real desktop mouse user
   (`.rp-site-block--coarse` is never present there). The margin-top MUST travel with the height raise
   here too: growing the plaque without it reopens the exact text overlap the round-1 fix closed, just
   on a device the width query doesn't reach. */
.rp-land-block.rp-site-block--coarse .rp-site-hidden-btn { height: 44px; }
.rp-land-block.rp-site-block--coarse .rp-site-auto-plaque { min-height: 44px; }
.rp-land-block.rp-site-block--coarse .rp-site-hidden-strip { margin-top: 18px; }
/* 🔴 Final review: the FOOTER plaque («Заполняется само из «Реквизитов»», a real link to /finance)
   sits OUTSIDE .rp-land-block, so the pointer-keyed twin above never reached it and it stayed at
   ~27px on a coarse-pointer tablet — while the width-keyed rule, being unscoped, already caught it.
   LandingPreviewSurface stamps the same `rp-site-block--coarse` marker on the footer wrapper (one
   vocabulary word for "this session has a coarse pointer", from the same probe). No margin-top
   partner is needed here: the --footer variant is position:static, so growing it pushes the preview
   below it down instead of overlapping anything. */
.rp-site-footer-plaque.rp-site-block--coarse .rp-site-auto-plaque { min-height: 44px; }

/* rp-site-footer-plaque (Task 15) — the public site's own footer, rendered read-only after the last
   block: no pencil, no rp-land-block class (so it never opens for editing), no click handler.
   rp-site-footer-preview gives it the tenant's template font/palette exactly like rp-land-preview does
   for a block, WITHOUT reusing that class name — see the doc-comment block above for why (a hidden-strip
   test asserts .rp-land-preview stays at its Task-17 floor of ONE — the site-header pseudo-block's own,
   always-on preview — when the only catalog block on screen is collapsed). */
.rp-site-footer-plaque {
  border: 1px dashed var(--border); border-radius: var(--radius-lg);
  padding: 14px 18px; margin-top: 4px;
}
.rp-site-footer-preview { margin-top: 0; }

/* rp-land-itemwrap / rp-land-itemdel (Task 15 — «Lists can only grow» fix) — a small circular delete
   button floating over a list item's own top-right corner, added ONLY while editing (see each block's
   own class-attribute suffix: `@(Editing ? " rp-land-itemwrap" : "")`), so the public read view never
   gains the position:relative context or the button. --left/--faq reposition it for the two blocks whose
   card already puts something else in the default corner (Formats' step-number badge, Faq's +/− icon). */
.rp-land-itemwrap { position: relative; }
.rp-land-itemwrap .rp-land-itemdel {
  position: absolute; top: -8px; right: -8px; z-index: 3;
  width: 20px; height: 20px; padding: 0; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--destructive); color: var(--destructive-foreground);
  border: 2px solid var(--card); cursor: pointer;
}
.rp-land-itemwrap .rp-land-itemdel:hover {
  background: color-mix(in srgb, var(--destructive) 85%, black);
}
.rp-land-itemwrap--left .rp-land-itemdel { left: -8px; right: auto; }
.rp-land-itemwrap--faq .rp-land-itemdel { top: 14px; right: 48px; }

/* rp-land-offwarn — inline honest-data warning shown only while the block that needs it is open
   (self-signup off / zero open schedule slots / the block itself is hidden). Generic warning strip —
   reused verbatim by later site-editor tasks, not specific to the landing block shape. */
.rp-land-offwarn {
  margin: 8px 0 12px; padding: 8px 12px; border-radius: 10px; font-size: 13px;
  color: var(--warning-muted-foreground, var(--foreground));
  background: var(--warning-muted, var(--muted));
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
}

/* rp-land-hint — small muted caption (e.g. the schedule block's live open-slot count). Restored (fix
   round 1, Important: the orphan sweep dropped this rule while LandingPreviewSurface.razor still
   emits the class — it was rendering at inherited body size/colour instead of as a hint). */
.rp-land-hint { font-size: 12.5px; color: var(--muted-foreground); line-height: 1.5; }

/* rp-site-empty-note (Task 4) — the CLOSED-state twin of rp-land-offwarn's zero-slot Schedule warning:
   sits where the (now-empty) real preview would have rendered, so the card is never a mute strip.
   Lives OUTSIDE rp-land-preview/rp-site-surface in the markup, so its <a> keeps real pointer-events
   (rp-site-surface disables them for every other in-card link — see LandingPreviewSurface's own note). */
.rp-site-empty-note {
  padding: 18px;
  font-size: 13.5px;
  color: var(--muted-foreground);
}
.rp-site-empty-note a { color: var(--primary); text-decoration: underline; }

.rp-land-preview { margin-top: 0; }

/* ── Service frame (Task 14 — click-to-edit, «Мой сайт - редизайн.dc.html» §Взаимодействие) ────────
   SiteBlockFrame's two bars: cabinet chrome, deliberately NOT themed by the tenant's template (the
   surrounding .rp-land-preview is), so a tutor never mistakes the editor for the page. */
.rp-site-frame-top {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  min-height: 46px; margin: -14px -18px 12px; padding: 0 18px;
  background: var(--primary); color: var(--primary-foreground);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  font-size: 13.5px; font-weight: 600;
}
.rp-site-frame-title { flex-shrink: 1; min-width: 0; }
.rp-site-frame-help {
  color: var(--primary-foreground); opacity: 0.85; font-size: 12.5px; font-weight: 600;
  text-decoration: underline; white-space: nowrap;
}
.rp-site-frame-help:hover { opacity: 1; }
.rp-site-frame-spacer { flex: 1; min-width: 8px; }
/* Border/hover tint derive from --primary-foreground (fix round 1, Minor) rather than a literal
   white — vivid's dark-mode --primary is a light blue with a near-black --primary-foreground, so a
   hardcoded rgba(255,255,255,…) read as an almost invisible border on an already-light fill. */
.rp-site-frame-hidebtn {
  flex-shrink: 0; height: 34px; padding: 0 14px;
  border: 1px solid color-mix(in srgb, var(--primary-foreground) 50%, transparent);
  border-radius: var(--radius-md);
  background: transparent; color: var(--primary-foreground);
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.rp-site-frame-hidebtn:hover {
  background: color-mix(in srgb, var(--primary-foreground) 12%, transparent);
}

.rp-site-frame-bottom {
  display: flex; align-items: center; flex-wrap: wrap; gap: 10px;
  min-height: 62px; margin: 12px -18px -14px; padding: 10px 18px;
  background: color-mix(in srgb, var(--primary) 7%, var(--card));
  border-top: 1.5px solid var(--primary);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}
.rp-site-frame-save,
.rp-site-frame-cancel,
.rp-site-frame-addbtn {
  flex-shrink: 0; height: 44px; padding: 0 16px; border-radius: var(--radius-md);
  font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.rp-site-frame-save { border: 0; background: var(--primary); color: var(--primary-foreground); }
.rp-site-frame-save:hover { opacity: 0.92; }
.rp-site-frame-cancel {
  border: 1px solid var(--border); background: var(--card); color: var(--foreground);
}
.rp-site-frame-cancel:hover { border-color: var(--primary); color: var(--primary); }
.rp-site-frame-addbtn {
  border: 1.5px dashed var(--border); background: transparent; color: var(--muted-foreground);
}
.rp-site-frame-addbtn:hover { border-color: var(--primary); color: var(--primary); }

/* SP5: the AI offer and its undo. Outline, not primary — «Сохранить» stays the one filled button in
   this bar, and 44px keeps the phone hit target at the size SP3 set for everything it exposed there.
   Colours follow Cancel/addbtn (var(--border)/var(--foreground)), NOT a literal white: this bar's own
   background is color-mix(var(--primary) 7%, var(--card)) — a near-card light tint, not the solid
   --primary fill the top bar has — so white text here would repeat the exact invisible-in-light-theme
   bug rp-site-frame-hidebtn was fixed away from (fix round 1, Minor). */
.rp-site-frame-aibtn, .rp-site-frame-undobtn {
  display: inline-flex; align-items: center; gap: 6px;
  min-height: 44px; padding: 0 14px; border-radius: var(--radius-md);
  background: transparent; border: 1px solid var(--border); color: var(--foreground);
  font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer; white-space: nowrap;
}
.rp-site-frame-aibtn:hover { border-color: var(--primary); color: var(--primary); }
.rp-site-frame-aibtn:disabled { opacity: .55; cursor: default; }
.rp-site-frame-aibtn:disabled:hover { border-color: var(--border); color: var(--foreground); }
.rp-site-frame-undobtn { border-style: dashed; }
.rp-site-frame-undobtn:hover { border-color: var(--primary); color: var(--primary); }

.rp-site-frame-hint {
  flex-basis: 100%; font-size: 12.5px; color: var(--muted-foreground);
}
@media (min-width: 560px) {
  .rp-site-frame-hint { flex-basis: auto; margin-left: auto; text-align: right; }
}

/* Dirty frame bottom bar tints toward --warning instead of --primary (Task 16 — the class was already
   applied by SiteBlockFrame, reserved but unstyled until now). */
.rp-site-frame-bottom--dirty { border-top-color: var(--warning, var(--primary)); }

/* rp-site-dirtybar (Task 16 — «Защита от потери правок»): a second, always-on reminder of the open
   block's unsaved edit, pinned to the bottom of the viewport so it survives scrolling a long block past
   the frame's own bottom bar. `position: sticky` (not `fixed`) — the surface has no independent scroll
   region of its own (the whole cabinet page scrolls), so sticky keeps it inside the surface's own
   layout flow instead of overlaying unrelated chrome (the app-bar, the mobile bottom nav) the way a
   viewport-fixed bar would. */
.rp-site-dirtybar {
  position: sticky; bottom: 12px; z-index: 5;
  display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin: 4px 0 10px; padding: 12px 16px;
  border: 1px solid color-mix(in srgb, var(--warning) 35%, var(--border));
  border-radius: var(--radius-lg);
  background: var(--card); box-shadow: var(--shadow-md);
}
.rp-site-dirtybar-dot {
  flex-shrink: 0; width: 8px; height: 8px; border-radius: 50%; background: var(--warning);
}
.rp-site-dirtybar-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.rp-site-dirtybar-title { font-size: 13.5px; font-weight: 600; }
.rp-site-dirtybar-sub { font-size: 12.5px; color: var(--muted-foreground); }
.rp-site-dirtybar-spacer { flex: 1; min-width: 8px; }
@media (max-width: 560px) {
  .rp-site-dirtybar { bottom: 4px; }
  .rp-site-dirtybar-text { flex-basis: 100%; order: 1; }
  .rp-site-dirtybar-spacer { display: none; }
}

/* The open block's own editable fields get a permanent (not hover/focus-only) dashed outline, so the
   55+ audience the design targets can see exactly what is editable without having to discover it.
   Background is a translucent tint of the FIELD'S OWN text colour, never var(--background): the text
   colour comes from the template scope (--tpl-ink or a section-local ink) while --background is the
   CABINET theme's — when their brightness matches (light theme × vivid, dark theme × nautical) the
   text disappeared entirely, contrast ~1.04:1 (audit 2026-08-02). currentColor keeps the pair
   self-consistent on ANY section background, including the hero gradients. */
.rp-land-block:not(.rp-site-block--idle) .rp-inline-edit {
  border: 1.5px dashed var(--primary); border-radius: 10px;
  background: color-mix(in srgb, currentColor 6%, transparent);
}

/* rp-inline-edit — borderless in-place inputs for the WYSIWYG landing editor (RpInlineText/RpInlineArea).
   Inherit the surrounding block typography; only a subtle hover/focus affordance distinguishes them
   from static text. */
.rp-inline-edit {
  font: inherit; color: inherit; line-height: inherit; letter-spacing: inherit;
  width: 100%; margin: 0; padding: 2px 4px;
  background: transparent; border: 1px solid transparent; border-radius: 6px;
  outline: none; box-sizing: border-box;
}
.rp-inline-edit::placeholder { color: var(--muted-foreground); opacity: .7; }
.rp-inline-edit:hover { border-color: color-mix(in srgb, var(--border) 70%, transparent); }
.rp-inline-edit:focus { border-color: var(--primary); background: var(--background); }
/* Same reasoning as the open-block rule above: the generic :focus falls back to the cabinet
   background, which inside a template-scoped section is exactly the invisible-text pair. */
.rp-land-block:not(.rp-site-block--idle) .rp-inline-edit:focus {
  background: color-mix(in srgb, currentColor 12%, transparent);
}
/* Inputs sized by CONTENT, not by a container that is itself content-sized: hero's eyebrow chip,
   the contacts channel pills and the stats value cells all wrap the input in an intrinsically-sized
   box, where width:100% resolves to the browser's default ~167px and the value clips (audit
   2026-08-02: «Астрономия и физика · онлайн» → «Астрономия и физик»). Progressive enhancement —
   Firefox/Safari keep today's behaviour. */
@supports (field-sizing: content) {
  .rp-land-block:not(.rp-site-block--idle) input.rp-inline-edit {
    field-sizing: content; width: auto; min-width: 96px; max-width: 100%;
  }
}
/* A placeholder longer than the field («Заголовок (необязательно)» at display size) clips mid-word
   without this — an ellipsis at least says "there is more". */
.rp-inline-edit:placeholder-shown { text-overflow: ellipsis; }
/* The nav preview is the real desktop header (Tailwind breakpoints are VIEWPORT-based, so at 1366px
   the full xl nav renders even inside a ~700px editor card) — let it scroll sideways instead of
   silently amputating «Контакты»/«Кабинет»/«Записаться» (audit 2026-08-02). */
.rp-site-navpreview { overflow-x: auto; }
.rp-inline-area { resize: none; overflow: hidden; field-sizing: content; min-height: 2.6em; }

/* Task 12: rp-site-surface (landing-blocks.css) disables pointer-events on every <a>/<summary>/<form>
   inside the shared landing blocks, so a real CTA link, a FAQ disclosure or the decorative feedback
   form never navigates/submits inside the cabinet preview. pointer-events is INHERITED, and several
   editable fields render their OWN in-place control nested inside exactly those elements — Hero's/
   Contacts'/Parents' CTA text, Contacts' four channel labels, a future Icon field inside a <summary> —
   so without restoring it here those fields are visible but unclickable with a mouse. Scoped to the
   controls themselves (not to <a>/<summary>/<form> broadly), which stay inert for the reasons in
   ContactsBlock's own doc comment. */
.rp-site-surface .rp-inline-edit,
.rp-site-surface .rp-icon-picker-trigger { pointer-events: auto; }

/* Inside a template card the hero photo widget sits in a ~180px column — without wrapping, the
   «Загрузить» label pokes past the card edge (audit 2026-08-02). Scoped to the preview: on the
   profile/brand pages the row has ample width and keeps its single-line layout. */
.rp-land-preview .rp-imgupl { flex-wrap: wrap; }

/* rp-icon-picker — in-place icon chooser (LandingIconPicker) for the WYSIWYG landing editor. */
.rp-icon-picker-trigger { display:inline-flex; align-items:center; justify-content:center;
  width:36px; height:36px; border-radius:10px; border:1px solid var(--border);
  background:var(--background); cursor:pointer; }
.rp-icon-picker-trigger:hover { border-color: var(--primary); }
.rp-icon-picker-menu { display:grid; grid-template-columns: 1fr 1fr; gap:2px; padding:6px; max-height:320px; overflow:auto; }
.rp-icon-picker-item { display:flex; align-items:center; gap:8px; }

/* ── «Мой сайт» hub — tabless page frame (my-site-redesign SP1 Task 13, Мой сайт.dc.html §2.1) ──────
   Replaces the wave-5 RpHubTabs strip: one vertical flow, header + a work canvas on var(--muted) holding
   the address line and the site card — «Настроить адрес» opens the SiteAddressDialog modal (rp-siteaddr*
   below) rather than expanding a panel in place. */
.rp-site2 { display: flex; flex-direction: column; }

.rp-site2-top {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 12px;
  min-height: 72px;
  padding: 12px 0;
  border-bottom: 1px solid var(--border);
}

.rp-site2-title {
  /* Now an <h2> (accessibility fix — the page previously carried zero heading elements); pin every
     property a browser's user-agent h2 rule would otherwise set (margin block-start/end, font-size,
     font-weight) so promoting the tag can't silently change the header's layout. */
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  letter-spacing: -0.01em;
  flex-shrink: 0;
}

.rp-site2-spacer { flex: 1; min-width: 8px; }

.rp-site2-btn {
  display: inline-flex; align-items: center; gap: 8px;
  height: 46px; padding: 0 18px;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--card); color: var(--foreground);
  font-size: 13.5px; font-weight: 600; text-decoration: none; white-space: nowrap; flex-shrink: 0;
}
.rp-site2-btn:hover { border-color: var(--primary); color: var(--primary); }
.rp-site2-btn--primary {
  border: 1.5px solid var(--primary); background: var(--primary); color: var(--primary-foreground);
}
.rp-site2-btn--primary:hover { opacity: 0.92; color: var(--primary-foreground); }
.rp-site2-btn--on { border-color: var(--primary); color: var(--primary); background: var(--secondary); }

/* SP3 Task 5: on a phone (RpViewportWatcher's coarse-pointer-OR-≤640px probe, SitePage's own `_mobile`)
   the header's own actions collapse to just the icon — a 44×44 tap target with the caption dropped
   from the markup entirely (an aria-label keeps the button named for a screen reader). This can fire
   independently of the ≤640px media query below (a wide-screen coarse-pointer tablet), so the base
   rule lives here, unconditional. */
.rp-site2-btn--icon {
  width: 44px;
  height: 44px;
  padding: 0;
  justify-content: center;
}

/* «Цвет и вид» popover (my-site-redesign Task 17, SiteThemePopover) — anchored under its trigger
   button, RpSelect's own pattern (rp-sel-overlay/rp-sel-pop, further below in the file): a transparent
   full-screen overlay catches an outside click and closes the popover, while the popover itself sits
   ABOVE it (higher z-index) inside a position:relative wrapper around just the trigger button so it
   doesn't drag the whole rp-site2-top header into a new stacking/positioning context. */
.rp-site-themebtn-wrap { position: relative; }
.rp-site-pop-overlay { position: fixed; inset: 0; z-index: 25; background: transparent; }
.rp-site-pop {
  position: absolute; top: calc(100% + 8px); left: auto; right: 0;
  width: 380px; max-width: calc(100vw - 32px);
  z-index: 30;
  max-height: min(560px, calc(100vh - 96px));
  overflow-y: auto;
  border: 1px solid var(--border); border-radius: var(--radius-lg);
  background: var(--card); box-shadow: var(--shadow-lg);
  padding: 16px;
  /* кнопка стоит у правого края .rp-site2-top, 380px вправо не помещаются на 1366px;
     зеркало мобильного прецедента :12346-12369 */
}
.rp-site-pop-title { font-size: 13.5px; font-weight: 700; margin-bottom: 10px; }
.rp-site-hexmore {
  display: flex; align-items: center; gap: 6px;
  border: 0; background: transparent; padding: 4px 0;
  color: var(--muted-foreground); font: inherit; font-size: 13px; font-weight: 600; cursor: pointer;
}
.rp-site-hexmore:hover { color: var(--primary); }
.rp-site-pop-lead {
  margin: 0 0 12px;
  font-size: 13px;
  line-height: 1.45;
  color: var(--muted-foreground);
}
.rp-site-pop-done { height: 46px; margin-top: 14px; }

/* Site-header pseudo-block (Task 17) — the RpImageUpload logo control + the «Название берётся…» hint
   line, stacked above the SiteNavBar preview inside the open frame (rp-land-preview, unchanged). */
.rp-site-header-edit { display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px; }

.rp-site2-work {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-top: 16px;
  padding: 24px;
  border-radius: var(--radius-lg);
  background: var(--muted);
}

.rp-site2-card {
  max-width: 780px;
  padding: 20px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--card);
  box-shadow: var(--shadow-xs);
}

/* SiteAddressLine — the public host, plain text, plus the «Настроить адрес» trigger. */
.rp-site2-addr {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}
.rp-site2-addr-text { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.rp-site2-addr-label { font-size: 12.5px; color: var(--muted-foreground); flex-shrink: 0; }
.rp-site2-addr-host { font-size: 14.5px; font-weight: 700; word-break: break-all; }
.rp-site2-addr-btn {
  display: inline-flex; align-items: center; gap: 6px;
  height: 36px; padding: 0 14px;
  border: 1px solid var(--border); border-radius: var(--radius-md);
  background: var(--card); color: var(--foreground);
  font: inherit; font-size: 12.5px; font-weight: 600; cursor: pointer; white-space: nowrap; flex-shrink: 0;
}
.rp-site2-addr-btn:hover { border-color: var(--primary); color: var(--primary); }

/* Task 14 review finding: while State.Value?.Slug is still null (before the FIRST ComputeState),
   SiteAddressLine used to render a bare ".repetitum.ru" for one frame — this placeholder stands in for
   that window at the same row height, so the address row doesn't collapse to nothing either. */
.rp-site2-addr--loading { min-height: 36px; }

@media (max-width: 640px) {
  /* 🔴 Fix round 1, Minor: .rp-site-themebtn-wrap is a flex ITEM in .rp-site2-top that isn't itself
     .rp-site2-btn, so the flex:1 rule below never reached it — «Цвет и вид» sat at its natural width
     while «Мастер настройки»/«Открыть сайт» stretched to fill the row either side of it. Giving the
     wrapper flex:1 too (and its own inner button width:100%) restores the even three-up row.
     Re-anchoring the popover itself is the other half: at desktop width the 380px panel anchors
     precisely under the trigger button (.rp-site-themebtn-wrap, position:relative) — on a narrow
     screen that same anchor can sit anywhere in a wrapped three-button row, so a fixed left:0/380px
     panel can run past the viewport's right edge regardless of max-width (max-width caps the panel's
     OWN size, not its position). Switching the positioning ANCESTOR to .rp-site2-top (the whole header
     row, made position:relative only in this breakpoint) instead — via .rp-site-themebtn-wrap:
     position:static, which drops it out of the ancestor chain the absolute panel resolves against —
     and spanning left:0/right:0 off that wider box removes the overflow risk regardless of which
     button in the row was clicked. */
  .rp-site2-top { min-height: 0; position: relative; }
  .rp-site2-btn { flex: 1; justify-content: center; height: 44px; padding: 0 10px; }
  .rp-site-themebtn-wrap { position: static; flex: 1; }
  .rp-site-themebtn-wrap .rp-site2-btn { width: 100%; }
  /* SP3 Task 5: at this width every rp-site2-btn already renders icon-only (rp-site2-btn--icon), so the
     even-stretch rules just above (added for the old always-text three-up row) would otherwise re-widen
     the 44×44 icon square via flex-basis:0% from flex:1 — flex-basis wins over an explicit width on the
     main axis, the same trap noted on .rp-siteaddr-addrow above. Both overrides sit AFTER the rules they
     override, at equal or higher selector specificity, so they win the cascade unconditionally. */
  .rp-site2-btn--icon { flex: 0 0 44px; padding: 0; }
  .rp-site-themebtn-wrap .rp-site2-btn--icon { width: 44px; }
  /* 🔴 Fix round 1, Important: the override above only reaches the BUTTON inside the wrap — the wrap
     itself is a separate flex ITEM (see the fix-round-1 comment above `.rp-site-themebtn-wrap { flex:
     1 }`) and kept that flex:1 regardless of what its child renders. A `flex:1` item's rendered width
     tracks how much free space the row has left to distribute, not its child's own size — so with the
     44px-pinned button flush-left inside it, the wrap can stretch well past 44px and leave dead space
     on its own right edge, throwing off the gaps on either side of the icon by an amount that varies
     with the row's free space (an independent repro — same bp.css + the blazorblueprint.css preflight,
     real tokens.css, Playwright at 375px — reproduced no visible stretch at 375px but a wrap several
     times the button's width at 640px; the exact figures are a function of the row's own width and
     don't generalize, which is why none are cited here). :has() (already used for the chat shell and
     the Blueprint portal overrides elsewhere in this file) scopes the fix to exactly the state that
     matters — a wrap whose button is in icon mode — without assuming the JS `_mobile` probe and this
     CSS breakpoint always agree. */
  .rp-site-themebtn-wrap:has(.rp-site2-btn--icon) { flex: 0 0 44px; }
  .rp-site-pop { left: 0; right: 0; width: auto; max-width: none; }
  /* 2026-08-02 (владелец): на 375px внутренности блоков превью не помещались — контейнер оставлял им
     ~283px (16px каркас + 16px панель + 14px карточка с каждой стороны), на ~92px УЖЕ реального
     телефона посетителя. Full-bleed: панель растворяется (фон/скругление долой, боковые -16px
     компенсируют padding каркаса .rp-shell__content — величины связаны, меняются только парой),
     но СВОЙ горизонтальный padding 16px сохраняет, чтобы баннеры и адресная строка не прилипали
     к краю экрана; карточка пробивается сквозь него собственными -16px до настоящего края. */
  .rp-site2-work {
    margin-left: -16px;
    margin-right: -16px;
    padding: 0 16px;
    background: transparent;
    border-radius: 0;
  }
  .rp-site2-card {
    margin: 0 -16px;
    padding: 0;
    border: 0;
    border-radius: 0;
    box-shadow: none;
  }
  /* Вводная строка «Нажмите на блок…» — единственный НЕ-блочный текст внутри карточки; без своего
     отступа она прилипла бы к краю после обнуления padding карточки. */
  .rp-site2-card .rp-land-intro { padding: 0 16px; }
  /* Лёгкий масштаб превью: zoom, НЕ transform — участвует в layout (высота сжимается сама, без
     JS-компенсации), внутренняя ширина блока автоматически 375/0.85 ≈ 441 виртуальных px («чуть
     больше места»), и — критично — zoom не создаёт containing block для position:fixed, так что
     MobileEditorShell и порталы Blueprint не ломаются (transform бы сломал). Сам MobileEditorShell —
     СОСЕД блоков в DOM (не потомок .rp-land-block), поэтому редактор остаётся 1:1 со своими
     44px-тапами. Карандаш-чип ужмётся визуально до ~31px — на телефоне он декоративен, блок
     открывается тапом по любому месту. */
  .rp-site2-card .rp-land-block,
  .rp-site2-card .rp-site-footer-plaque { zoom: 0.85; }
  .rp-site2-addr { flex-direction: column; align-items: stretch; }
  /* 42px → 44px (final review): the ONE hit on this page's address row, two pixels under the floor
     the rest of the sweep applied. */
  .rp-site2-addr-btn { width: 100%; height: 44px; justify-content: center; }
}

/* ── Onboarding «сайт за минуту» (wave 5 Task 12 · Онбординг.dc.html) ─────────
   Focus-mode page on ReaderLayout: own sticky screen header + a scrolling body
   carrying the three phases (Brief / Generating / Preview). Colours via tokens
   only, so dark mode flips for free. The preview block cards are rendered by
   LandingPreviewSurface (rp-land-*, Task 10) — not restyled here. */
@keyframes rp-onb-pulse { 0%, 100% { opacity: 0.45; } 50% { opacity: 1; } }

.rp-onb {
  display: flex;
  flex-direction: column;
  min-height: 100vh;
  background: var(--background);
  color: var(--foreground);
}

.rp-onb-header {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 12px;
  height: 58px;
  padding: 0 24px;
  border-bottom: 1px solid var(--border);
  background: var(--card);
}

.rp-onb-brand { display: inline-flex; align-items: center; gap: 10px; flex-shrink: 0; }
.rp-onb-mark { display: block; }
/* Theme-swap the brand mark in pure CSS — theme.js sets `.dark` on <html> pre-paint, so no
   ThemeController is needed on this ReaderLayout page (which never inits it). */
.rp-onb-mark--dark { display: none; }
.dark .rp-onb-mark--light { display: none; }
.dark .rp-onb-mark--dark { display: block; }
.rp-onb-brand-word {
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--primary);
}

.rp-onb-phase {
  font-size: 12.5px;
  color: var(--muted-foreground);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.rp-onb-spacer { flex: 1; min-width: 8px; }

.rp-onb-credits {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 34px;
  padding: 0 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--accent);
  color: var(--accent-foreground);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
  flex-shrink: 0;
}

/* Outlined button, not bare text — owner feedback: as a ghost link «Заполню позже» got lost
   among the header content and didn't read as an actionable control. */
.rp-onb-later {
  height: 34px;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--card);
  color: var(--foreground);
  font: inherit;
  font-size: 12.5px;
  font-weight: 600;
  cursor: pointer;
  flex-shrink: 0;
  white-space: nowrap;
}
.rp-onb-later:hover:not(:disabled) { border-color: var(--foreground); background: var(--accent); }
.rp-onb-later:disabled { opacity: 0.5; cursor: default; }

.rp-onb-body {
  flex: 1;
  width: 100%;
  padding: 32px 24px 80px;
}

/* ── Brief phase ─────────────────────────────────────────────────────────── */
.rp-onb-h1 {
  font-size: 24px;
  font-weight: 700;
  letter-spacing: -0.01em;
  margin: 0 0 6px;
}

.rp-onb-lead {
  font-size: 13.5px;
  color: var(--muted-foreground);
  line-height: 1.6;
  margin: 0 0 22px;
}

.rp-onb-field { display: block; margin-bottom: 6px; }
.rp-onb-label {
  display: block;
  font-size: 12.5px;
  font-weight: 600;
  margin-bottom: 5px;
}

.rp-onb-textarea,
.rp-onb-input {
  width: 100%;
  border: 1px solid var(--input);
  border-radius: var(--radius-md);
  background: var(--card);
  color: var(--foreground);
  font: inherit;
  font-size: 13.5px;
}
.rp-onb-textarea {
  padding: 12px;
  line-height: 1.55;
  resize: vertical;
  min-height: 150px;
}
.rp-onb-input { height: 42px; padding: 0 12px; }
.rp-onb-textarea:focus-visible,
.rp-onb-input:focus-visible {
  outline: none;
  border-color: var(--primary);
}

.rp-onb-hint {
  font-size: 12px;
  color: var(--muted-foreground);
  line-height: 1.55;
  margin: 0 0 20px;
}
.rp-onb-hint a { color: var(--primary); text-decoration: none; }
.rp-onb-hint a:hover { text-decoration: underline; }

.rp-onb-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 14px;
  margin-bottom: 20px;
}

.rp-onb-actions {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
  align-items: center;
  flex-wrap: wrap;
}

.rp-onb-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 40px;
  padding: 0 18px;
  border: 0;
  border-radius: var(--radius-md);
  font: inherit;
  font-size: 13.5px;
  font-weight: 600;
  cursor: pointer;
}
.rp-onb-btn:disabled { opacity: 0.6; cursor: default; }
.rp-onb-btn--primary { background: var(--primary); color: var(--primary-foreground); padding: 0 20px; }
.rp-onb-btn--ghost { background: transparent; color: var(--muted-foreground); }
.rp-onb-btn--ghost:hover:not(:disabled) { color: var(--foreground); }
.rp-onb-btn--outline { border: 1px solid var(--border); background: var(--card); color: var(--foreground); }

/* ── Welcome (orientation) phase ─────────────────────────────────────────── */
.rp-onb-welcome { max-width: 560px; margin: 0 auto; }
.rp-onb-welcome-loading { display: flex; justify-content: center; padding: 80px 0; }
.rp-onb-choices { display: grid; gap: 12px; margin: 24px 0 18px; }
.rp-onb-choice {
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  text-align: left;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--card);
  color: var(--foreground);
  padding: 16px 18px;
  font: inherit;
  cursor: pointer;
  transition: border-color 0.15s, box-shadow 0.15s;
}
.rp-onb-choice:hover:not(:disabled) {
  border-color: var(--primary);
  box-shadow: 0 2px 10px color-mix(in srgb, var(--primary) 12%, transparent);
}
.rp-onb-choice:disabled { opacity: 0.6; cursor: default; }
.rp-onb-choice-ico {
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  border-radius: var(--radius-md);
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--accent);
  color: var(--accent-foreground);
}
.rp-onb-choice-text { display: flex; flex-direction: column; gap: 3px; min-width: 0; flex: 1; }
.rp-onb-choice-title { font-size: 14.5px; font-weight: 700; }
.rp-onb-choice-sub { font-size: 12.5px; color: var(--muted-foreground); line-height: 1.45; }
.rp-onb-choice-arrow { flex-shrink: 0; color: var(--muted-foreground); display: inline-flex; }
.rp-onb-lookaround { display: flex; margin: 0 auto; }
.rp-onb-welcome-note {
  text-align: center;
  font-size: 12.5px;
  color: var(--muted-foreground);
  margin: 10px 0 0;
}

/* ── Generating phase ────────────────────────────────────────────────────── */
.rp-onb-gen { max-width: 640px; margin: 60px auto 0; text-align: center; }
.rp-onb-spark {
  width: 64px;
  height: 64px;
  margin: 0 auto 20px;
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-foreground);
  display: flex;
  align-items: center;
  justify-content: center;
  animation: rp-onb-pulse 1.6s ease-in-out infinite;
}
.rp-onb-gen-title { font-size: 17px; font-weight: 700; margin-bottom: 6px; }
.rp-onb-gen-sub { font-size: 13px; color: var(--muted-foreground); }

.rp-onb-skeletons {
  max-width: 420px;
  margin: 28px auto 0;
  display: grid;
  gap: 10px;
}
.rp-onb-skel {
  border-radius: var(--radius-md);
  background: var(--muted);
  animation: rp-onb-pulse 1.6s ease-in-out infinite;
}

/* ---- Onboarding questionnaire (six click-first steps + final) -------------------------------- */
.rp-onb-q { max-width: 640px; margin: 0 auto; }
.rp-onb-q-why {
  margin: -4px 0 22px;
  font-size: 14px;
  line-height: 1.55;
  color: var(--muted-foreground);
}
.rp-onb-q-spheres {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 10px;
}
.rp-onb-q-sphere {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  min-height: 88px;
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: 12px;
  background: var(--card);
  color: var(--foreground);
  text-align: left;
  cursor: pointer;
  transition: border-color .12s, background .12s, box-shadow .12s;
}
.rp-onb-q-sphere:hover { border-color: var(--foreground); }
.rp-onb-q-sphere.is-on {
  border-color: var(--primary);
  background: color-mix(in srgb, var(--primary) 8%, var(--card));
  box-shadow: 0 0 0 1px var(--primary) inset;
}
.rp-onb-q-sphere-ico { display: inline-flex; color: var(--primary); }
.rp-onb-q-sphere-label { font-size: 13.5px; font-weight: 600; line-height: 1.3; }
.rp-onb-q-sub { margin-top: 22px; }
.rp-onb-q-sub-title,
.rp-onb-q-seg-title { font-size: 13px; font-weight: 700; margin: 14px 0 8px; }
.rp-onb-q-sub-title { margin-top: 0; }
.rp-onb-q-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.rp-onb-q-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-height: 38px;
  padding: 0 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--card);
  color: var(--foreground);
  font-size: 13.5px;
  line-height: 1.2;
  cursor: pointer;
  transition: border-color .12s, background .12s;
}
.rp-onb-q-chip:hover { border-color: var(--foreground); }
.rp-onb-q-chip.is-on {
  border-color: var(--primary);
  background: color-mix(in srgb, var(--primary) 10%, var(--card));
  color: var(--primary);
  font-weight: 600;
}
.rp-onb-q-chip.is-free { font-style: italic; }
.rp-onb-q-free { display: flex; gap: 8px; margin-top: 10px; }
.rp-onb-q-free .rp-onb-input { flex: 1; min-width: 0; }
.rp-onb-q-free .rp-onb-btn { height: 42px; white-space: nowrap; }
.rp-onb-q-seg { display: inline-flex; flex-wrap: wrap; gap: 6px; }
.rp-onb-q-seg-btn {
  min-height: 40px;
  padding: 0 16px;
  border: 1px solid var(--border);
  border-radius: 10px;
  background: var(--card);
  color: var(--foreground);
  font-size: 13.5px;
  cursor: pointer;
}
.rp-onb-q-seg-btn:hover { border-color: var(--foreground); }
.rp-onb-q-seg-btn.is-on {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--primary-foreground);
  font-weight: 600;
}
.rp-onb-q-city { margin-top: 16px; }
.rp-onb-q-nav { justify-content: flex-start; }
.rp-onb-gen-line { color: var(--primary); font-weight: 600; margin-bottom: 4px; }

/* ── Onboarding shell: rail + kicker + body + footer (Онбординг v2) ──────────
   One chrome for the three flows (site questionnaire, invite, course). The rail is a
   sidebar on wide screens and gone on narrow ones, where the kicker «Шаг N из M» is
   the only progress cue and the footer sticks to the bottom. */
.rp-onb-shell {
  display: grid;
  grid-template-columns: 200px minmax(0, 640px);
  justify-content: center;
  column-gap: 40px;
  align-items: start;
}
.rp-onb-shell--norail { grid-template-columns: minmax(0, 640px); }
.rp-onb-rail {
  position: sticky;
  top: 82px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding-top: 6px;
}
.rp-onb-rail-row {
  display: flex;
  align-items: center;
  gap: 11px;
  width: 100%;
  padding: 7px 10px;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--muted-foreground);
  font: inherit;
  font-size: 13px;
  font-weight: 500;
  text-align: left;
  cursor: default;
  transition: background 0.15s, color 0.15s;
}
.rp-onb-rail-row.is-link { cursor: pointer; }
.rp-onb-rail-row.is-link:hover { background: var(--accent); color: var(--foreground); }
.rp-onb-rail-row.is-done { color: var(--foreground); }
.rp-onb-rail-row.is-cur {
  background: color-mix(in srgb, var(--primary) 8%, transparent);
  color: var(--foreground);
  font-weight: 700;
}
.rp-onb-rail-row.is-skip { opacity: 0.45; }
.rp-onb-rail-dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: 1px solid var(--border);
  font-size: 11.5px;
  font-weight: 700;
  color: var(--muted-foreground);
  background: transparent;
  transition: all 0.2s;
}
.rp-onb-rail-row.is-cur .rp-onb-rail-dot {
  border-color: var(--primary);
  color: var(--primary);
  background: var(--card);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--primary) 16%, transparent);
}
.rp-onb-rail-row.is-done .rp-onb-rail-dot {
  border-color: var(--primary);
  background: var(--primary);
  color: var(--primary-foreground);
}
.rp-onb-rail-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rp-onb-main { min-width: 0; }
.rp-onb-kicker {
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--muted-foreground);
  margin: 0 0 8px;
}
.rp-onb-foot { margin-top: 24px; }
.rp-onb-shell .rp-onb-q { max-width: none; margin: 0; }
.rp-onb-hint--error { color: var(--destructive); }
.rp-onb-check {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-top: 16px;
  font-size: 13.5px;
  line-height: 1.45;
  cursor: pointer;
}
.rp-onb-check input { margin: 3px 0 0; accent-color: var(--primary); }

/* Done screens (invite / course): checkmark, link row, the «Ещё для старта» strip. */
.rp-onb-done-ico { display: inline-flex; color: var(--success); margin-bottom: 10px; }
.rp-onb-link-row { display: flex; gap: 8px; margin: 4px 0 18px; }
.rp-onb-link-row .rp-onb-input { flex: 1; min-width: 0; }
.rp-onb-link-row .rp-onb-btn { height: 42px; white-space: nowrap; }
.rp-onb-done-actions { justify-content: flex-start; margin-bottom: 6px; }
.rp-onb-next { margin-top: 28px; padding-top: 22px; border-top: 1px solid var(--border); }
.rp-onb-next-title { font-size: 13px; font-weight: 700; margin-bottom: 10px; }
.rp-onb-choices--compact { margin: 0; gap: 8px; }
.rp-onb-choice--compact { padding: 12px 14px; }
.rp-onb-choice--compact .rp-onb-choice-ico { width: 36px; height: 36px; }
.rp-onb-choice--compact .rp-onb-choice-title { font-size: 13.5px; }
.rp-onb-choice--compact .rp-onb-choice-sub { font-size: 12px; }
/* The course body inside the shell reuses the dialog's field classes — only the «Курс создан»
   screen needs re-centring, since the strip sits between its title and its buttons. */
.rp-onb-course .rp-cwiz-done { align-items: flex-start; text-align: left; padding-top: 0; }
.rp-onb-course .rp-cwiz-done-actions { flex-direction: row; flex-wrap: wrap; margin-top: 16px; }

/* Hub cards: ✓ state + the «Следующий шаг» / «Рекомендуем» badge. */
.rp-onb-choice.is-done .rp-onb-choice-ico { background: var(--success); color: #fff; }
.rp-onb-choice.is-done .rp-onb-choice-title { color: var(--muted-foreground); }
.rp-onb-choice-title { display: inline-flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rp-onb-choice-badge {
  display: inline-flex;
  align-items: center;
  height: 20px;
  padding: 0 8px;
  border-radius: 999px;
  background: color-mix(in srgb, var(--primary) 12%, transparent);
  color: var(--primary);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.01em;
}

@media (max-width: 900px) {
  .rp-onb-shell { grid-template-columns: minmax(0, 1fr); }
  .rp-onb-rail { display: none; }
}
@media (max-width: 600px) {
  .rp-onb-foot {
    position: sticky;
    bottom: 0;
    margin: 20px -14px 0;
    padding: 10px 14px;
    background: var(--background);
    border-top: 1px solid var(--border);
  }
  .rp-onb-link-row { flex-direction: column; }
}

/* «Мой сайт» one-shot banner after onboarding published the site. */
.rp-site2-onboarded { margin-bottom: 12px; }

@media (max-width: 768px) {
  .rp-onb-header { height: 54px; padding: 0 14px; gap: 10px; }
  .rp-onb-body { padding: 24px 14px 72px; }
  .rp-onb-grid { grid-template-columns: 1fr; }
  /* Drop the «РЕПЕТИТУМ» wordmark (the mark stays) so the phase caption «Предпросмотр сайта»
     has room to render in full instead of ellipsising to «Педпросмо…» (owner feedback). */
  .rp-onb-brand-word { display: none; }
  /* Same squeeze, second round (prod smoke 2026-08-22): the credits chip + «Заполню позже» cut
     «Шаг 1 из 2 — расскажите о себе» down to «Ш.» — keep the step counter, drop the tail, and
     shorten the chip to «✨50» so the counter actually has the pixels to render. */
  .rp-onb-phase-tail { display: none; }
  .rp-onb-credits-word { display: none; }
  .rp-onb-q-spheres { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rp-onb-q-free { flex-direction: column; }
}

