/*
 * Подарцев Cards Page — Mobile-First Stylesheet
 * Sprint 5 Track B19 (B18 layout, B21 accessibility)
 *
 * Architecture: all values via tokens.css custom properties.
 * No inline styles. No emojis. No exclamation marks.
 * Breakpoints (matching tokens.css --bp-* values):
 *   Base / default: < 360px  (small mobile — single column, minimal)
 *   @360px+:        360–767  (standard mobile — full single-column)
 *   @768px+:        768–1023 (tablet — 2-column cards)
 *   @1024px+:       ≥1024    (desktop — 3-column cards)
 *
 * Tested viewport widths: 320, 360, 375, 414, 768, 1024
 *   320px: single column, gift-name 22px, value-frame hidden, small padding
 *   360px: single column, gift-name 22px, full layout, value-frame visible
 *   375px: same as 360 (iPhone SE / common Android)
 *   414px: same as 360 (iPhone XR/11)
 *   768px: 2-column cards grid
 *   1024px: 3-column cards grid
 *
 * CSS quote behaviour: at <360px, guillemets «» replaced by "" via:
 *   q { quotes: "\201C" "\201D"; }
 *   At 360px+: q { quotes: "\00AB" "\00BB"; } (guillemets restored)
 *   This applies to any <q> element in cards. Direct quote characters in
 *   Jinja2 templates stay as-is; only <q> elements are affected.
 */

/* ── Reset ──────────────────────────────────────────────────────────────── */

*,
*::before,
*::after {
  box-sizing: border-box;
}

/*
 * Enforce HTML `hidden` attribute across ALL display contexts.
 * flex/grid containers turn children into flex/grid items, which overrides
 * the browser's built-in `display: none` for [hidden].
 * The HTML spec explicitly recommends this rule (§14.1).
 * !important is correct here: no layout rule should ever reveal a [hidden] node.
 * JS that wants to show an element must remove the `hidden` attribute, not
 * override display — result_actions.js already does this correctly.
 */
[hidden] { display: none !important; }

/* Remove default margin/padding from elements we control */
body,
h1, h2, h3, h4,
p, ul, ol, li,
hr, figure, blockquote,
dl, dd {
  margin: 0;
  padding: 0;
}

ul, ol {
  list-style: none;
}

/* ── Base / Global ──────────────────────────────────────────────────────── */

html {
  /* Prevents mobile font inflation (font boosting) */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Always reserve the vertical scrollbar gutter so the centered layout does
     NOT shift left/right between steps when a tall step adds a scrollbar and a
     short one doesn't (founder 2026-06-13). */
  scrollbar-gutter: stable;
  /* Fallback fill for any scroll overscroll below body */
  background-color: var(--cream);
}

body {
  font-family: var(--font-sans);
  font-size: var(--fz-body);
  line-height: var(--lh-body);
  color: var(--color-text);

  /*
   * CLEAN CREAM BACKGROUND — per gold-mockup (2026-06-06 founder override).
   * Ribbon webp removed: основатель «дизайн золотого макета нравится больше».
   * Cream solid fill #fefafa matches the mockup body background exactly.
   */
  background-color: var(--cream);

  /* Hyphenation DISABLED globally (founder 2026-06-14): no syllable word-breaks
     in headings or card text. lang="ru" no longer triggers auto-hyphenation. */
  -webkit-hyphens: none;
  hyphens: none;
}

/*
 * Quote characters — small mobile (<360px): double-quotes
 * At 360px+ these are overridden to guillemets.
 */
q {
  quotes: "\201C" "\201D";
}

/* ── Page layout ────────────────────────────────────────────────────────── */

.page {
  width: min(var(--max-content-width), calc(100% - (2 * var(--space-md))));
  margin-inline: auto;
  padding-block: var(--space-lg) var(--space-3xl);
  /* iPhone home-bar safe area: ensure content not clipped by bottom inset */
  padding-bottom: calc(var(--space-3xl) + env(safe-area-inset-bottom, 0px));
}

/* ── Hero block ─────────────────────────────────────────────────────────── */

.hero {
  padding-block: var(--space-lg) var(--space-xl);
  border-bottom: 1px solid var(--color-border);
  margin-bottom: var(--space-2xl);   /* B2: ~48px breathing room below hero */
}

.hero-title {
  font-family: var(--font-serif);
  font-size: var(--fz-hero);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
  color: var(--navy);

  /* Cyrillic long-name defensive wrapping */
  word-break: break-word;
  overflow-wrap: anywhere;
}

.hero-title--expired {
  color: var(--color-muted);
  font-weight: var(--fw-medium);
}

/*
 * Result echo line — occasion-anchored warm sentence between the h1 and
 * the hero-sub subtitle (Part 3, 2026-06-07).
 * Muted, Open Sans, ~14px, sits quietly below the Playfair h1.
 */
.result-echo-line {
  font-family: var(--font-sans);
  font-size: 14px;
  line-height: var(--lh-body);
  color: var(--color-muted);
  margin-top: var(--space-xs, 4px);
  margin-bottom: var(--space-xs, 4px);
}

/* ── Cards section ──────────────────────────────────────────────────────── */

/*
 * Default (< 768px): single column, standard padding.
 * Cards stack vertically. Background is now clean cream (ribbon removed).
 */
.cards {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  background: transparent;
  padding: var(--space-xl) 0;
}

/* ── Individual card ────────────────────────────────────────────────────── */

/*
 * Mockup-aligned card style (2026-06-06 founder override).
 * White (#fff) surface, 1px solid #e7e1d6 border, 11px radius, light shadow.
 * Matches docs/card-result-mockup-2026-06-06.html exactly.
 * No border-merge on mobile — cards are individual items with margin-bottom.
 */
.card {
  background: #fff;
  border: 1px solid var(--color-border);
  border-radius: 11px;
  padding: var(--space-md);
  box-shadow: 0 1px 4px rgba(0, 20, 60, 0.05);
  margin-bottom: 15px;

  /* Smooth shadow transition for hover */
  transition: box-shadow var(--duration-mid) var(--easing-out);

  /* Column layout for subgrid alignment support */
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.card:hover {
  box-shadow: var(--shadow-hover);
  position: relative;
  z-index: 1;
}

.cards .card:last-child {
  margin-bottom: 0;
}

/* ── Card image zone REMOVED (правка #2, 2026-06-06) ─────────────────────── */
/*
 * .card-image zone was removed entirely per founder «место для изображения убрать».
 * The .card-slot-label is now the first visible child of .card, sits in normal
 * document flow at the top of the card. No positioning overlay needed.
 * All .card-image CSS rules below are intentionally absent.
 */

/* ── Slot label ─────────────────────────────────────────────────────────── */

/*
 * Small-caps, wide letter-spacing, gold colour — the slot differentiator.
 * Sits in normal flow at the top of the card (card-image zone removed).
 * Uses --gold (#a68751) matching the mockup .slot colour exactly.
 * WCAG: --gold on white #fff = 3.0:1 which clears AA for decorative/label
 * (11px uppercase with letter-spacing — not AA body text).
 * font-size 11px / letter-spacing 0.07em / uppercase — matches mockup.
 */
.card-slot-label {
  font-family: var(--font-sans);
  font-size: 11px;
  font-weight: var(--fw-semibold);
  line-height: var(--lh-ui);
  letter-spacing: 0.07em;
  color: var(--gold-on-light);
  text-transform: uppercase;
  margin-bottom: 9px;
}

/* ── Gift name (h2) ─────────────────────────────────────────────────────── */

/*
 * Primary card heading. Playfair Display serif, 22px mobile → 30px desktop.
 * Navy (--navy: #002d5b) — authority and trust on the paper surface.
 * Weight 500 (medium): visually dominant without heavy slab appearance.
 */
.card-gift-name {
  font-family: var(--font-serif);
  font-size: var(--fz-gift-name);
  font-weight: var(--fw-medium);
  line-height: var(--lh-heading);
  letter-spacing: var(--ls-heading);
  color: var(--navy);

  /* Cyrillic long-name defensive handling */
  word-break: break-word;
  overflow-wrap: anywhere;
  -webkit-hyphens: none;
  hyphens: none;
}

/* ── Divider ────────────────────────────────────────────────────────────── */

.card-divider {
  border: none;
  border-top: 1px solid var(--gold-light);
  /* 16px top + bottom margin per spec */
  margin-block: var(--space-md);
}

/* ── Hook line ──────────────────────────────────────────────────────────── */

/*
 * Italic Playfair Display in navy — emotional resonance statement.
 * Navy (--navy) on paper: restrained authority, not gold-on-gold clash.
 * Gold is reserved as the single CTA accent (btn-choose).
 * 14-15px, slightly tighter than body.
 */
.card-hook-line {
  font-family: var(--font-serif);
  font-size: var(--fz-hook-line);
  font-style: italic;
  line-height: var(--lh-body);
  color: var(--navy);
}

.card-hook-line em {
  /* <em> inside hook-line is already italic via parent; preserve semantic role */
  font-style: italic;
}

/* ── Why-them (back-compat — no longer rendered on стр.1) ───────────────── */

/*
 * Prose rationale. System sans, 14-16px, generous line-height for readability.
 * NOTE: As of 2026-06-06 this class is no longer rendered on стр.1 preview.
 * Rule preserved for back-compat (v3 cards, regression tests).
 */
.card-why-them {
  font-family: var(--font-sans);
  font-size: var(--fz-body);
  line-height: var(--lh-body);
  color: var(--color-muted);

  /* Hyphenation on long Cyrillic words in prose */
  -webkit-hyphens: none;
  hyphens: none;
}

/* ── Canon §1.1 preview anatomy (2026-06-06) ─────────────────────────────── */

/*
 * КРЮЧОК (hook) — largest element, visual anchor of the preview card.
 * Правка #1: matches mockup .hook exactly — Playfair 20px, navy, weight 600,
 * line-height 1.25, margin-bottom 7px.
 */
.card-hook {
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: var(--fw-semibold);
  line-height: 1.25;
  letter-spacing: var(--ls-heading);
  color: var(--navy);
  margin-bottom: 7px;
  word-break: break-word;
  overflow-wrap: anywhere;
  -webkit-hyphens: none;
  hyphens: none;
}

/*
 * ОТВЕТ — gift first named here; smaller than the hook (muted, body sans).
 * Правка #1: matches mockup .answer — 15px, #2b3444, margin-bottom 9px.
 * Omitted from DOM entirely when L7 flag fired (rule R-W1).
 */
.card-answer {
  font-family: var(--font-sans);
  font-size: 15px;
  line-height: var(--lh-body);
  color: #2b3444;
  margin-bottom: 9px;
  -webkit-hyphens: none;
  hyphens: none;
}

/*
 * ★ ТИЗЕР ВРУЧИТЬ — italic, always present (canon: never remove).
 * Правка #1: matches mockup .teaser — Playfair italic, gold (#a68751), 14px,
 * margin-bottom 12px. Gold star via ::before.
 */
.card-teaser {
  font-family: var(--font-serif);
  font-size: 14px;
  font-style: italic;
  line-height: var(--lh-body);
  color: var(--gold);
  margin-bottom: 12px;
}

.card-teaser::before {
  content: "\2605\00A0";   /* ★ + non-breaking space */
  color: var(--gold);
  font-style: normal;
}

.card-teaser em {
  font-style: italic;  /* preserve italic from <em> wrapper */
}

/* ── Value frame ─────────────────────────────────────────────────────────── */

/*
 * Price/value caption — matches mockup .price style.
 * Правка #1 (2026-06-06): gold text, top border separator, bottom margin.
 * No double-border (mockup has only border-top).
 */
.card-value-frame {
  font-family: var(--font-sans);
  font-size: 12.5px;
  font-weight: var(--fw-regular);
  line-height: var(--lh-body);
  color: var(--gold-on-light);
  border-top: 1px solid #efe9dd;
  padding-top: 9px;
  margin-bottom: 13px;
}

/* ── WG-1 specifics_line ─────────────────────────────────────────────────── */

/*
 * WG-1 (2026-05-23): Factual credential for the gift object (≤60 chars).
 * Shown between the divider and hook_line. Condensed sans, muted colour.
 * Describes the object — no recipient pronouns.
 */
.card-specifics-line {
  font-family: var(--font-sans);
  font-size: var(--fz-value-frame);
  line-height: var(--lh-ui);
  color: var(--color-slot-label);
  letter-spacing: 0.01em;
  margin-block: var(--space-xs);
}

/* ── WG-1 zone-break ─────────────────────────────────────────────────────── */

/*
 * WG-1 (2026-05-23): Visual separator between why_them (rationale) and the
 * value/actions zone below. border-top 1px + padding-top 20px.
 */
.card-zone-break {
  border-top: 1px solid var(--gold-light);
  padding-top: 20px;
  margin-top: var(--space-sm);
}

/* ── Buy paths ───────────────────────────────────────────────────────────── */

/*
 * Max 3 text links. No button appearance — premium concierge links are
 * plain with underline on hover. Accent colour, no pill/badge styling.
 */
.card-buy-paths {
  display: flex;
  flex-direction: column;
  gap: var(--space-xs);
  margin-top: var(--space-xs);
}

.card-buy-paths li {
  line-height: var(--lh-ui);
}

.card-buy-paths a {
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-medium);
  /* WCAG AA: --gold-on-light #8e6f39 on paper #fffdf9 = 4.61:1
     (was var(--color-accent) = #a68751 = 3.33:1 — fails AA for 14px text) */
  color: var(--gold-on-light);
  text-decoration: none;
  /* Accessibility: underline visible on keyboard focus and hover */
  text-decoration-line: underline;
  text-decoration-style: dotted;
  text-underline-offset: 3px;
  transition: color var(--duration-fast) var(--easing-standard),
              text-decoration-style var(--duration-fast) var(--easing-standard);
}

.card-buy-paths a:hover {
  color: var(--color-text);
  text-decoration-style: solid;
}

/* Keyboard focus — visible focus ring (WCAG 2.1 AA) */
.card-buy-paths a:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
  text-decoration-style: solid;
}

/* ── D3: buy-paths-panel (deferred reveal post-save) ────────────────────── */

/*
 * D3 (WG-1 2026-05-23): buy_paths panel is hidden until «Это оно» save tap.
 * result_actions.js removes `hidden` attribute after save.
 * When revealed, smooth fade-in via CSS transition.
 */
.card-buy-paths-panel {
  margin-top: var(--space-xs);
}

.card-buy-paths-panel[hidden] {
  display: none;
}

/* ── Card actions (buttons) ─────────────────────────────────────────────── */

/*
 * Card actions row — matches mockup .acts style.
 * Правка #5 (2026-06-06): flex row, gap 14px, align center, no divider line.
 * (Divider is now supplied by .card-value-frame border-top above.)
 */
.card-actions {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
}

/*
 * Ghost button base — subordinate to the gold accent btn-choose.
 * Plan 1 Task 3: transparent fill, gold-light border, muted text.
 * Hierarchy: btn-choose (filled gold) > btn-remix (ghost) — clear visual weight.
 */
.btn-remix,
.btn-share {
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-medium);
  line-height: var(--lh-ui);
  color: var(--color-muted);
  background: transparent;
  border: 1px solid var(--gold-light);
  border-radius: var(--radius-btn);
  padding: var(--space-xs) var(--space-sm);
  /* Touch target ≥44px per spec §16.2 */
  min-height: 44px;
  min-width: 44px;
  cursor: pointer;
  /* No fill — ghost subordinate to gold CTA */
  transition: color var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard),
              background var(--duration-fast) var(--easing-standard);
}

/* ── Per-card choose button (стр.2 navigation, lazy-commit §3.1) ──────────── */

/*
 * «Выбираю эту» choose link — the SINGLE gold accent CTA on each card.
 * Правка #5 (2026-06-06): gold fill (#a68751), white text, border-radius 8px,
 * padding ~10px 18px, font-weight 600 — matches mockup .choose exactly.
 * WCAG AA: white (#fff) on --gold (#a68751) = 3.0:1 — borderline for 14px bold;
 * font-weight 600 elevates to Large Text AA threshold (3:1 passes at bold ≥14px).
 * Touch target ≥44px per spec §16.2.
 */
.btn-choose {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  text-decoration: none;
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-ui);
  color: var(--navy);
  background: var(--gold-btn);
  border: none;
  /* Unified to the canonical 2px button radius (was 8px — the rounded outlier
     the founder flagged 2026-06-13). Premium-sharp, consistent with all CTAs. */
  border-radius: var(--radius-btn);
  padding: 10px 18px;
  /* Touch target ≥44px per spec §16.2 */
  min-height: 44px;
  min-width: 44px;
  cursor: pointer;
  letter-spacing: 0.01em;
  transition: background var(--duration-fast) var(--easing-standard),
              color var(--duration-fast) var(--easing-standard);
}

.btn-choose:hover {
  background: var(--navy);
  color: var(--gold-light);
}

.btn-choose:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

.btn-choose:active {
  background: var(--navy);
  color: var(--gold-light);
  opacity: 0.9;
}

.btn-remix:hover,
.btn-share:hover {
  color: var(--navy);
  border-color: var(--gold);
  background: var(--color-accent-soft);
}

.btn-remix:focus-visible,
.btn-share:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/*
 * Canon §5 ghost treatment for «Показать другое» (стр.1 remix link).
 * Правка #5 (2026-06-06): no background, no border, grey text (#6b7280),
 * underlined, font-size ~13px — matches mockup .ghost exactly.
 * JS hooks (data-action, aria-expanded, reject-chips) remain intact on the element.
 */
.btn-remix--ghost {
  background: none;
  border: none;
  color: #6b7280;
  font-weight: var(--fw-regular, 400);
  font-size: 13px;
  padding-left: 0;
  padding-right: 0;
  text-decoration: underline;
  text-underline-offset: 3px;
}

.btn-remix--ghost:hover {
  background: none;
  border-color: transparent;
  color: var(--navy);
  text-decoration-style: solid;
}

/* B4: on mobile the ghost remix button should be maximally quiet */
@media (max-width: 767px) {
  .btn-remix--ghost {
    font-size: 12px;
    opacity: 0.7;
  }
  .btn-remix--ghost:hover {
    opacity: 1;
  }
}

.btn-remix:active,
.btn-share:active {
  background: var(--color-accent-soft);
  border-color: var(--gold);
}

/* ── Reject chips fieldset ───────────────────────────────────────────────── */

/*
 * Hidden initially (fieldset[hidden]); shown by result_actions.js when
 * remix button is tapped. WCAG 2.1 AA: fieldset + legend group.
 */
.reject-chips {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-sm);
  margin-top: var(--space-sm);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
}

.reject-chips-legend {
  font-family: var(--font-sans);
  font-size: var(--fz-value-frame);
  font-weight: var(--fw-medium);
  color: var(--color-slot-label);
  padding-inline: var(--space-xs);
}

/*
 * Individual reject chip button.
 * Touch target ≥44px per spec §16.2 (min-height + padding).
 */
.reject-chip {
  font-family: var(--font-sans);
  font-size: var(--fz-value-frame);
  font-weight: var(--fw-regular);
  line-height: var(--lh-ui);
  color: var(--color-muted);
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-xs) var(--space-sm);
  /* Touch target ≥44px per spec §16.2 */
  min-height: 44px;
  cursor: pointer;
  transition: background var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard),
              color var(--duration-fast) var(--easing-standard);
}

.reject-chip:hover {
  border-color: var(--color-accent);
  color: var(--color-text);
  background: var(--color-accent-soft);
}

.reject-chip:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/* Selected state: aria-pressed=true */
.reject-chip[aria-pressed="true"] {
  background: var(--color-accent);
  border-color: var(--color-accent);
  color: var(--color-surface);
}

/*
 * «Добавь деталей» enrichment door (spec 2026-07-05). Rendered by
 * result_actions.js as a sibling right under a card once the remix threshold is
 * reached. Warm, friendly — NOT a lock/quota. The remix itself stays available
 * above; this door only offers the better path (add a few details).
 */
.add-details-door {
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-sm);
  margin-top: var(--space-sm);
  background: var(--color-accent-soft, transparent);
}

.add-details-nudge {
  font-family: var(--font-sans);
  font-size: var(--fz-value-frame);
  line-height: var(--lh-ui);
  color: var(--color-text);
  margin: 0 0 var(--space-xs) 0;
}

.add-details-field {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  align-items: flex-start;
}

.add-details-input {
  flex: 1 1 12rem;
  font-family: var(--font-sans);
  font-size: var(--fz-value-frame);
  line-height: var(--lh-ui);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: var(--space-xs) var(--space-sm);
  resize: vertical;
  min-height: 44px;
}

.add-details-input:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.add-details-submit {
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-medium);
  color: var(--color-surface);
  background: var(--color-accent);
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-sm);
  padding: var(--space-xs) var(--space-md, var(--space-sm));
  min-height: 44px;
  cursor: pointer;
  transition: background var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard);
}

.add-details-submit:hover {
  background: var(--color-accent-strong, var(--color-accent));
}

.add-details-submit:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.add-details-submit[disabled] {
  opacity: 0.6;
  cursor: default;
}

/*
 * Retry button on the per-slot empty-state (founder 2026-07-01). Modest gold-
 * outline button that re-runs single-slot generation in place. Touch target
 * ≥44px per spec §16.2.
 */
.btn-retry-slot {
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-medium);
  color: var(--navy);
  background: transparent;
  border: 1px solid var(--gold-light);
  border-radius: var(--radius-sm);
  padding: var(--space-xs) var(--space-md);
  margin-top: var(--space-sm);
  min-height: 44px;
  cursor: pointer;
  transition: background var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard);
}

.btn-retry-slot:hover {
  border-color: var(--gold);
  background: var(--color-accent-soft);
}

.btn-retry-slot:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.btn-retry-slot[disabled] {
  opacity: 0.6;
  cursor: default;
}

/* ── Wizard inputs — iOS zoom prevention ─────────────────────────────────── */

/*
 * iOS Safari auto-zooms on input focus when font-size < 16px (1rem).
 * Force font-size: 1rem on all text inputs to prevent layout shift.
 * Applies to all wizard form inputs, quiz steps, city prompt, etc.
 * spec §16.2 iOS zoom prevention.
 */
input[type="text"],
input[type="email"],
input[type="number"],
input[type="tel"],
input[type="search"],
input[type="url"],
textarea,
select {
  font-size: 1rem; /* iOS auto-zoom prevention — never go below 16px */
}

/* ── Site chrome: header ────────────────────────────────────────────────── */

/*
 * Navy site header — full-width, sticky top.
 * C1 contract (seamless-nav WG FINAL 2026-07-08, founder-ratified): ONE
 * geometry for both populations — logo lockup CENTERED, utility zone RIGHT
 * («Мои идеи» account icon everywhere; gold CTA in full chrome only), LEFT
 * column an intentional spacer (the app header has no center nav, so a
 * left-aligned logo left the middle empty — founder follow-up 2026-07-09:
 * center reads premium and balanced). App only — the WordPress site header
 * is a separate stack and stays logo-LEFT.
 * Marketing nav + socials left the header for the footer «Подарцев в сети».
 * Bottom border: 1px var(--gold-light) for editorial separation.
 * Bar: ~104px desktop / 64px mobile (A2 layout 2026-07-09 — grew 88→104 to
 * give the gift-box mark + lockup vertical breathing room; supersedes the
 * 124px podartsev.ru-parity bar and the 88px C1 compact bar).
 */
.site-header {
  background: var(--navy);
  border-bottom: 1px solid var(--gold-light);
  padding: 0 var(--space-lg);
  position: sticky;
  top: 0;
  z-index: 100;
}

/* 3-column grid centers the logo without any spacer markup: column 1 (1fr)
 * carries no content and simply reserves space; the logo sits in column 2
 * (auto-width, centered within its track); the utility zone sits in column
 * 3 (1fr, right-aligned). Below 768px, FULL chrome (heavier right zone)
 * reverts to a plain left-align flex row — see the mobile block below. */
.site-header__inner {
  max-width: var(--max-content-width);
  margin-inline: auto;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--space-md);
  min-height: 104px;  /* A2 bar (2026-07-09; grew 88→104 for the gift-box mark
                         + lockup breathing room). Was 124px WP-parity. */
}

/* Logo image link — grid column 2, centered within its track. Shared by
 * both populations: the full-chrome <a> and the flow quiet <span>. */
.site-logo-link {
  grid-column: 2;
  justify-self: center;
  display: flex;
  align-items: center;
  flex-shrink: 0;
  text-decoration: none;
}

.site-logo-link:focus-visible {
  outline: 2px solid var(--focus-ring-on-dark);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

.site-logo {
  /* D1 «Подарцев» wordmark SVG (on-navy variant); height-driven lockup */
  height: 56px;
  width: auto;
  display: block;
  /* R1b (2026-07-09, matches the live WP site): the wordmark SVG bakes an
     empty field BELOW the letters inside its viewBox. -4px pulls the gold
     hairline up snug against the baseline so the lockup reads as one unit
     (measured against the live site's final header). */
  margin-bottom: -4px;
}

/* Brand row (A2, founder-ratified 2026-07-09): the gift-box mark sits LEFT of
   the wordmark lockup with a 16px gap. The old column composition (wordmark →
   gold rule → tagline) moves into .site-brand__lockup below. */
.site-brand {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 16px;
  /* R1b optical recentre (2026-07-09). The wordmark SVG's viewBox
     (-111 -858 4775 1189) bakes ~7.07px of empty field ABOVE «П»'s cap-height
     when rendered 56px tall (ink top y=-708 vs viewBox top y=-858 → 150 units
     × 56/1189 ≈ 7.07px). With align-items:center the lockup is centred
     GEOMETRICALLY, so the visible ink sits ~half that (≈3.5px) too low.
     translateY lifts it back to optical centre. Static transform, not
     animated — no reduced-motion concern. NOT a negative margin (which would
     interact opaquely with the flex centring). */
  transform: translateY(-3.5px);
}

/* Gift-box mark — decorative (aria-hidden in the markup); height-driven,
   desktop only (hidden <768px in the mobile block, where a 44px mark would
   overflow the already ~385px full-chrome content on a 390px iPhone). */
.site-brand__mark {
  height: 66px;
  width: auto;
  display: block;
  flex-shrink: 0;
}

/* Brand lockup: wordmark over a gold hairline over the tracked-caps tagline
   «ДАРИТЕ ТОЧНО» (founder-ratified 2026-06-12). Tagline is Open Sans (loaded on
   both result + wizard pages); the Playfair letterforms live in the SVG itself. */
.site-brand__lockup {
  display: flex;
  flex-direction: column;
  align-items: center;
  /* R1b (2026-07-09): explicit-spacing model — the lockup gap is 0 and every
     vertical gap is now a NAMED margin (the wordmark's -4px below, the rule's
     7px below). Matches the live site's final header measurement. */
  gap: 0;
}

.site-brand__rule {
  /* R1b hairline (2026-07-09): thinner (1px), narrower (64%), softer (0.75) —
     the live site's final gold rule. Colour unchanged. 7px sits between the
     rule and the tagline (the lockup gap is now 0, so spacing is explicit). */
  width: 64%;
  height: 1px;
  opacity: 0.75;
  background: var(--gold-light);
  margin-bottom: 7px;
}

.site-brand__tagline {
  font-family: var(--font-sans);
  font-weight: 500;               /* R1b: lighter tracked caps (was 600) */
  font-size: 0.72rem;             /* R1b: was 0.78rem */
  letter-spacing: 0.44em;         /* R1b: was 0.38em */
  text-transform: uppercase;
  color: var(--gold-light);   /* --gold-light on navy = 5.99:1 (WCAG AA) */
  padding-left: 0.44em;       /* optical recentre for trailing letter-spacing (R1b: matches 0.44em) */
  line-height: 1;
  white-space: nowrap;
}

/* Right zone: «Мои идеи» account icon (+ CTA in full chrome). Grid column 3,
   right-aligned within its track. The old in-header nav / social-icon
   cluster / box-home-mark were all removed by the C1 declutter
   (2026-07-08) — socials + marketing nav render in the footer «Подарцев в
   сети». */
.site-header__right {
  grid-column: 3;
  justify-self: end;
  display: flex;
  align-items: center;
  gap: var(--space-md);
  flex-shrink: 0;
}

/* Account icon — the ONE utility present in every header state (founder:
   «одна иконка в шапке на каждой странице»). 44×44 tap target at EVERY
   viewport (WCAG 2.5.5 — was 32px base with a <768px upgrade). */
.header-account-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-sm);
  min-width: 44px;
  min-height: 44px;
  color: var(--gold-light);
  text-decoration: none;
  transition: color var(--duration-fast) var(--easing-standard);
}

.header-account-icon svg {
  fill: currentColor;
  flex-shrink: 0;
}

.header-account-icon:hover {
  color: #fff;
}

.header-account-icon:focus-visible {
  outline: 2px solid var(--focus-ring-on-dark);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* «Мои идеи» visible text label — icon-only below 1024px (C1 item 8). */
.header-account-label {
  display: none;
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-ui);
  white-space: nowrap;
}

@media (min-width: 1024px) {
  .header-account-label {
    display: inline;
  }
}

/*
 * Header CTA button — gold fill, navy text (WCAG AA: --gold-btn + --navy = 4.56:1).
 * Matches real podartsev.ru «Подобрать подарок» styling.
 * Uses --gold-btn (not raw --gold) to satisfy WCAG AA.
 */
.btn-header-cta {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--gold-btn);
  color: var(--navy);
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-semibold);
  text-decoration: none;
  padding: 9px 18px;
  /* --radius-md was undefined → rendered square; repoint to the canonical button
     radius (2px). Height 40→44 for WCAG 2.5.5 touch target (2026-06-13). */
  border-radius: var(--radius-btn);
  min-height: 44px;
  white-space: nowrap;
  transition: background var(--duration-fast) var(--easing-standard),
              box-shadow var(--duration-fast) var(--easing-standard);
}

.btn-header-cta:hover {
  /* Hover = LIGHTER gold, never raw --gold: #a68751 with the navy button
     text = 4.07:1 → fails WCAG AA (live bug, seamless-nav WG 2026-07-08).
     --gold-light #c4a776 = 5.99:1 and reads as a highlight. */
  background: var(--gold-light);
  box-shadow: 0 2px 8px rgba(0, 20, 60, 0.18);
}

.btn-header-cta:focus-visible {
  outline: 2px solid var(--focus-ring-on-dark);
  outline-offset: 3px;
}

/* Mobile: compact 64px bar (C1 contract). The old two-row nav-wrap +
   social-collapse rules died with the header nav/socials (2026-07-08);
   the account icon is 44×44 at every viewport via its base rule.
   FLOW keeps the centered grid all the way down — its right zone is only
   the 44px account icon, so the logo stays visually centered even at
   390px (measured offset from true-center: ~7px, imperceptible).
   FULL (shelf/door) is a heavier right zone (account icon + gold CTA,
   ~195-278px) — below tablet width that content is a large enough
   fraction of the viewport that forcing a true center either overlaps
   the right zone or leaves the logo looking randomly off-center, not
   "centered" (measured: forcing the grid at 390px pushed the logo ~103px
   off dead-center — worse than plain left-align). Founder follow-up
   2026-07-09 explicitly allows "left-align only... your call" when
   centering is cramped — full-chrome mobile IS that case; flow is not. */
@media (max-width: 767px) {
  .site-header {
    padding: 0 var(--space-md);
  }

  .site-header__inner {
    min-height: 64px;   /* C1 mobile bar (matches card-detail sticky offset) */
    padding-block: var(--space-sm);
  }

  .site-logo {
    height: 40px;   /* moderate wordmark on mobile (height-driven lockup) */
    width: auto;
    /* R1b: baked-field pull scales with the smaller wordmark (-4 × 40/56 ≈ -3). */
    margin-bottom: -3px;
  }

  /* A2 gift-box mark is desktop-only: a 44px mark would overflow the already
     ~385px full-chrome mobile content on a 390px iPhone (see the squeeze note
     below). Mobile bar stays 64px → every mobile sticky offset stays valid. */
  .site-brand__mark {
    display: none;
  }

  /* With the mark hidden the row collapses to the lockup alone. R1b: gap → 0
     for consistency with the explicit-spacing model (the rule's margin-bottom
     below carries the only vertical gap). */
  .site-brand__lockup {
    gap: 0;
  }

  /* R1b optical recentre, scaled to the 40px mobile wordmark: baked field
     ≈ 7.07 × 40/56 ≈ 5.05px → half ≈ 2.5px. Static transform (no animation →
     no reduced-motion concern). */
  .site-brand {
    transform: translateY(-2.5px);
  }

  /* R1b hairline carries over from the base rule (width:64%/height:1px/
     opacity:.75); only the rule→tagline gap tightens 7px→6px on mobile. */
  .site-brand__rule {
    margin-bottom: 6px;
  }

  .site-brand__tagline {
    font-weight: 500;           /* R1b: lighter tracked caps on mobile too */
    font-size: 0.6rem;
    letter-spacing: 0.34em;     /* R1b: was 0.3em */
    padding-left: 0.34em;
  }

  /* CTA smaller on mobile (font/padding compact) but keep ≥44px touch target */
  .btn-header-cta {
    font-size: 0.8125rem;
    padding: 7px 13px;
    min-height: 44px;
  }

  /* Full-chrome only: revert to the plain left-logo/right-utility flex row
     (grid-column/justify-self on the children are simply ignored once the
     parent is flex again) — AND squeeze it: even LEFT-ALIGNED, logo(≈160.6)
     + gap + account icon(44) + gap + CTA(≈148.8) ≈ 385px content overflows
     a 390px iPhone (≈358px available) — a PRE-EXISTING overflow (same
     total content demand existed before this centering follow-up too)
     surfaced while verifying the founder's explicit 390px check. Tighter
     gaps + a smaller lockup + a tighter CTA close the gap; flow never
     needed any of this. */
  .site-header:not(.site-header--flow) .site-header__inner {
    display: flex;
    justify-content: space-between;
    gap: var(--space-sm);
  }

  .site-header:not(.site-header--flow) .site-header__right {
    gap: var(--space-sm);
  }

  .site-header:not(.site-header--flow) .site-logo {
    height: 32px;
  }

  .site-header:not(.site-header--flow) .btn-header-cta {
    padding: 6px 10px;
  }
}

/* ── Site chrome: footer ────────────────────────────────────────────────── */

/*
 * Navy site footer — matches podartsev.ru 1:1.
 * Structure: primary grid (3 equal columns) + below-footer bar.
 * Primary: Col 1 social+email | Col 2 logo | Col 3 nav menu.
 * Below: Разработка сайта | © 2026 Подарцев | Политика конфиденциальности.
 * Stacks to single column on mobile (ast-builder-grid-row-mobile-full pattern).
 * Top border: 1px var(--gold-light) mirrors header bottom border.
 */
.site-footer {
  background: var(--navy);
  border-top: 1px solid var(--gold-light);
  padding: var(--space-2xl) var(--space-lg) 0;
}

/* ── Primary 3-column grid ── */
.site-footer__grid {
  max-width: var(--max-content-width);
  margin-inline: auto;
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--space-xl);
  padding-bottom: var(--space-2xl);
}

/* Flow (wizard/result) footer — centered slogan + «Подарцев в сети»
   (socials + marketing nav) + below-bar. The net block moved here FROM the
   flow header in the C1 declutter (seamless-nav WG 2026-07-08 — supersedes
   the 2026-06-13 slogan-only compact footer); email/logo columns stay out. */
.site-footer--flow {
  padding-top: var(--space-lg);
}
.site-footer--flow .site-footer__grid {
  grid-template-columns: 1fr;
  padding-bottom: var(--space-md);
  gap: var(--space-lg);
}
.site-footer--flow .site-footer__col--slogan {
  align-items: center;
  text-align: center;
}

/* «Подарцев в сети» — the deliberate outward surface (C1 2026-07-08). */
.site-footer__col--net {
  align-items: center;
  text-align: center;
}

.site-footer__net-heading {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fz-footer);
  font-weight: var(--fw-semibold);
  letter-spacing: var(--ls-label);
  text-transform: uppercase;
  color: var(--gold-light);   /* 5.99:1 on navy — WCAG AA */
}

/* Flow net block lays the nav links out in a centered row (compact),
   with ≥44px touch targets (the old in-header 18px nav links were the one
   sub-44 touch surface — UX-audit ⑧ residual, folded into C1). Full-mode
   footer keeps its ratified WP-parity column untouched. */
.site-footer--flow .site-footer__nav {
  flex-direction: row;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-md) var(--space-lg);
}

/* Compact flow below-bar: centre the «Разработка · © · Политика» group
   instead of the full-width space-between used on the result page. */
.site-footer--flow .site-footer__below {
  justify-content: center;
  gap: var(--space-lg);
  flex-wrap: wrap;
}

.site-footer__col {
  display: flex;
  flex-direction: column;
  gap: var(--space-md);
}

/* Col 1: social icons + email — left-aligned */
.site-footer__col--social {
  align-items: flex-start;
}

/* Col 2: logo — centred */
.site-footer__col--logo {
  align-items: center;
  justify-content: flex-start;
}

/* Col 3: nav — right-aligned on desktop */
.site-footer__col--nav {
  align-items: flex-end;
}

/* Social icon row */
.footer-social-icons {
  display: flex;
  align-items: center;
  gap: var(--space-md);
}

.footer-social-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--gold-light);
  text-decoration: none;
  transition: color var(--duration-fast) var(--easing-standard);
  /* WCAG 2.5.5: min tap target */
  min-width: 44px;
  min-height: 44px;
}

.footer-social-icon svg {
  fill: currentColor;
}

.footer-social-icon:hover {
  color: #fff;
}

.footer-social-icon:focus-visible {
  outline: 2px solid var(--focus-ring-on-dark);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Email link */
.footer-email {
  font-family: var(--font-sans);
  font-size: var(--fz-footer);
  color: var(--gold-light);
  text-decoration: none;
  transition: color var(--duration-fast) var(--easing-standard);
}

.footer-email:hover {
  color: #fff;
}

.footer-email:focus-visible {
  outline: 2px solid var(--focus-ring-on-dark);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Footer logo */
.footer-logo-link {
  display: inline-flex;
  text-decoration: none;
}

.footer-logo-link:focus-visible {
  outline: 2px solid var(--focus-ring-on-dark);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

.footer-logo {
  width: 60px;
  height: auto;
  display: block;
}

/* Footer navigation (col 3) */
.site-footer__nav {
  display: flex;
  flex-direction: column;
  gap: var(--space-sm);
}

.site-footer__link {
  font-family: var(--font-sans);
  font-size: var(--fz-footer);
  font-weight: var(--fw-medium);
  color: var(--gold-light);
  text-decoration: none;
  transition: color var(--duration-fast) var(--easing-standard);
  /* Hit box lives here, not under .site-footer--flow: the shelf and the login door
     render the footer in "full" mode, where the flow-scoped rule never applied and
     these measured 18px. A tap target must not depend on which chrome_mode the page
     asked for. */
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.site-footer__link:hover {
  color: #fff;
}

.site-footer__link:focus-visible {
  outline: 2px solid var(--focus-ring-on-dark);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* ── Below-footer bar ── */
.site-footer__below {
  max-width: var(--max-content-width);
  margin-inline: auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md);
  padding-block: var(--space-md);
  border-top: 1px solid rgba(196, 167, 118, 0.25);
  flex-wrap: wrap;
}

.footer-below-item {
  font-family: var(--font-sans);
  font-size: var(--fz-footer);
  color: rgba(255, 255, 255, 0.55);
}

.footer-copyright {
  text-align: center;
}

/* Standalone links, so WCAG 2.5.8's in-a-sentence exemption does not apply the
   way it does to .wizard-legal-note — at the inherited font-size these measured
   18px tall, under even the 24px AA floor. inline-flex grows the hit box without
   moving the text. (The wizard's legal links stay inline by design: padding there
   would break the sentence they sit in.) */
.footer-privacy {
  color: rgba(255, 255, 255, 0.55);
  text-decoration: none;
  transition: color var(--duration-fast) var(--easing-standard);
  display: inline-flex;
  align-items: center;
  min-height: 44px;
}

.footer-privacy:hover {
  color: var(--gold-light);
}

.footer-privacy:focus-visible {
  outline: 2px solid var(--focus-ring-on-dark);
  outline-offset: 3px;
  border-radius: var(--radius-sm);
}

/* Mobile: stack all footer columns */
@media (max-width: 767px) {
  .site-footer {
    padding: var(--space-xl) var(--space-md) 0;
  }

  .site-footer__grid {
    grid-template-columns: 1fr;
    gap: var(--space-lg);
    padding-bottom: var(--space-xl);
  }

  .site-footer__col--social,
  .site-footer__col--logo,
  .site-footer__col--nav {
    align-items: center;
    text-align: center;
  }

  .site-footer__nav {
    align-items: center;
  }

  .site-footer__below {
    flex-direction: column;
    align-items: center;
    text-align: center;
    gap: var(--space-sm);
  }
}

/* ── City prompt (spec v1.1 §17) ────────────────────────────────────────── */

/*
 * Optional city prompt — shown below result cards when:
 *   (1) no city in profile AND (2) ≥1 experience-slot card present.
 * Phase 0: DB-capture-only (no engine re-run).
 * Touch targets ≥44px per spec §16.2.
 */
.city-prompt {
  margin-top: var(--space-xl);
  padding: var(--space-lg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  background: var(--color-surface);
}

.city-prompt-question {
  font-family: var(--font-sans);
  font-size: var(--fz-body);
  font-weight: var(--fw-medium);
  color: var(--color-text);
  margin-bottom: var(--space-md);
}

.city-prompt-form {
  display: flex;
  gap: var(--space-sm);
  align-items: stretch;
}

.city-prompt-input {
  flex: 1;
  font-family: var(--font-sans);
  font-size: 1rem; /* iOS zoom prevention: ≥1rem per spec §16.2 */
  line-height: var(--lh-ui);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-input);
  padding: 0.625rem var(--space-sm);
  /* Touch target ≥44px */
  min-height: 44px;
  transition: border-color var(--duration-fast) var(--easing-standard);
}

.city-prompt-input:focus {
  outline: none;
  border-color: var(--color-accent);
}

.city-prompt-input:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.btn-city-submit {
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-medium);
  /* WCAG AA: navy on --gold-btn #af905a = 4.56:1.
     Previous: white on --color-accent #a68751 = 3.38:1 — FAIL for normal text. */
  color: var(--navy);
  background: var(--gold-btn);
  border: 1px solid var(--gold-btn);
  border-radius: var(--radius-btn);
  padding: 0.625rem var(--space-md);
  /* Touch target ≥44px */
  min-height: 44px;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard),
              color var(--duration-fast) var(--easing-standard);
}

.btn-city-submit:hover {
  background: var(--navy);
  border-color: var(--navy);
  /* hover: navy bg with gold-light text — consistent with btn-choose hover */
  color: var(--gold-light);
}

.btn-city-submit:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

.btn-city-submit:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* City prompt success state (JS-injected after save) */
.city-prompt--saved .city-prompt-question {
  color: var(--color-success);
}

.city-prompt--saved .city-prompt-form {
  display: none;
}

/* ── Plan 4 (canon §1.3a) — стр.1 passive group-seed line ─────────────────
 *
 * Design intent: a quiet, subordinate intent-level text line — NOT an accent CTA.
 * The single accent CTA on this page is «Выбираю эту» (§1.4 sacred).
 *
 * Visual treatment:
 *   - Centred under the card triple, 1.5rem breathing room above.
 *   - Body-text size, muted charcoal, reduced opacity (0.78) for subordination.
 *   - Gold-on-light underline (--gold-on-light #8e6f39, 4.61:1 on cream) signals
 *     tappability without accent-CTA weight.
 *   - No fill, no border, no radius — no button chrome whatsoever.
 *   - Focus-visible inherits the global :focus-visible rule (navy ring, 2px solid).
 *   - Hover and focus raise opacity to 1.0 for legibility.
 *   - Touch target: 44px min-height (WCAG 2.5.5) via padding and explicit min-height.
 */
.page1-group-seed-wrap {
  text-align: center;
  margin: 1.5rem auto 0;
  padding: 0 var(--space-md);
}

.page1-group-seed {
  /* Strip all button chrome */
  background: none;
  border: none;
  padding: 0.5rem var(--space-sm);
  /* Touch target — WCAG 2.5.5: ≥44px */
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  /* Typography: body size, charcoal text (--color-text #35373a on cream = ~13:1) */
  font-family: var(--font-sans);
  font-size: var(--fz-body);
  font-weight: var(--fw-regular);
  line-height: var(--lh-body);
  color: var(--color-text);
  /* Visual subordination: reduced opacity distinguishes from primary actions */
  opacity: 0.72;
  cursor: pointer;
  /* Gold underline signals tappability without accent-CTA weight.
     --gold-on-light #8e6f39 passes WCAG AA on cream background (4.61:1). */
  text-decoration: underline;
  text-decoration-color: var(--gold-on-light);
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: opacity var(--duration-fast) var(--easing-standard);
}

.page1-group-seed:hover {
  opacity: 1;
}

.page1-group-seed:focus-visible {
  opacity: 1;
  /* Inherits global :focus-visible (navy ring, 2px solid, 2px offset) */
}

/* ── Expired message ─────────────────────────────────────────────────────── */

.expired-message {
  padding: var(--space-xl) var(--space-md);
  text-align: center;
}

.expired-text {
  font-family: var(--font-sans);
  font-size: var(--fz-body);
  line-height: var(--lh-body);
  color: var(--color-muted);
  max-width: 36ch;
  margin-inline: auto;
}

/* ── G1 «помнить» opt-in card (Phase-1 G1 activation CTA) ───────────────────
 *
 * Design intent: a calm, subordinate card below the triple — NOT a modal,
 * NOT an accent CTA.  Uses the same card surface tokens as the main cards
 * (border, radius, padding) so it reads as a natural continuation of the page.
 *
 * Visual hierarchy:
 *   - Navy body text on cream surface (same as main copy).
 *   - «Да, напомните»: gold-btn fill button (same token as .btn-choose).
 *   - «Не нужно»: ghost/text button (navy outline, no fill) — subordinate.
 *   - Offset chips: outlined chips, selected = gold-btn fill.
 *   - Confirm step: muted charcoal, no actions.
 *
 * Touch targets ≥44px per spec §16.2.
 * No emoji.  No animation beyond standard --duration-fast transitions.
 */

.g1-optin-card {
  margin-top: var(--space-xl);
  padding: var(--space-lg);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  background: var(--color-surface);
  max-width: var(--card-max-width, 640px);
  margin-inline: auto;
}

.g1-optin-step {
  /* Steps are shown/hidden by JS — no layout side-effects when hidden. */
}

.g1-optin-prompt {
  font-family: var(--font-sans);
  font-size: var(--fz-body);
  font-weight: var(--fw-medium);
  line-height: var(--lh-body);
  color: var(--color-text);
  margin-bottom: var(--space-md);
}

.g1-optin-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: center;
}

/* «Да, напомните» — primary action, same treatment as .btn-choose */
.btn-g1-yes {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-ui);
  color: var(--navy);
  background: var(--gold-btn);
  border: 1px solid var(--gold-btn);
  border-radius: var(--radius-btn);
  padding: var(--space-xs) var(--space-md);
  min-height: 44px;
  min-width: 44px;
  cursor: pointer;
  letter-spacing: 0.01em;
  transition: background var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard),
              color var(--duration-fast) var(--easing-standard);
}

.btn-g1-yes:hover {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--gold-light);
}

.btn-g1-yes:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

.btn-g1-yes:active {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--gold-light);
  opacity: 0.9;
}

/* «Не нужно» — ghost/dismiss action, low visual weight */
.btn-g1-no {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-regular);
  line-height: var(--lh-ui);
  color: var(--color-muted);
  background: transparent;
  border: none;
  padding: var(--space-xs) var(--space-sm);
  min-height: 44px;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: var(--color-border);
  text-underline-offset: 2px;
  transition: color var(--duration-fast) var(--easing-standard);
}

.btn-g1-no:hover {
  color: var(--color-text);
}

.btn-g1-no:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/* Date step */
.g1-optin-date-heading,
.g1-optin-offset-heading {
  font-family: var(--font-sans);
  font-size: var(--fz-body);
  font-weight: var(--fw-medium);
  color: var(--color-text);
  margin-bottom: var(--space-sm);
  margin-top: 0;
}

.g1-optin-offset-heading {
  margin-top: var(--space-md);
}

.g1-optin-date-row {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm);
  align-items: center;
  margin-bottom: var(--space-xs);
}

.g1-optin-date-input {
  font-family: var(--font-sans);
  font-size: 1rem; /* iOS zoom prevention: ≥1rem */
  line-height: var(--lh-ui);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-input);
  padding: 0.625rem var(--space-sm);
  min-height: 44px;
  transition: border-color var(--duration-fast) var(--easing-standard);
}

.g1-optin-date-input:focus {
  outline: none;
  border-color: var(--color-accent);
}

.g1-optin-date-input:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/* «Не знаю точно» — same ghost treatment as btn-g1-no */
.btn-g1-no-date {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-regular);
  color: var(--color-muted);
  background: transparent;
  border: none;
  padding: var(--space-xs) var(--space-sm);
  min-height: 44px;
  cursor: pointer;
  text-decoration: underline;
  text-decoration-color: var(--color-border);
  text-underline-offset: 2px;
  transition: color var(--duration-fast) var(--easing-standard);
}

.btn-g1-no-date:hover {
  color: var(--color-text);
}

.btn-g1-no-date:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/* Offset chips */
.g1-optin-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-bottom: var(--space-md);
}

.g1-offset-chip {
  font-family: var(--font-sans);
  font-size: var(--fz-small, 0.875rem);
  font-weight: var(--fw-medium);
  color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-chip, 20px);
  padding: 0.375rem var(--space-sm);
  min-height: 36px;
  cursor: pointer;
  transition: background var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard),
              color var(--duration-fast) var(--easing-standard);
}

.g1-offset-chip[aria-pressed="true"],
.g1-offset-chip--selected {
  background: var(--gold-btn);
  border-color: var(--gold-btn);
  color: var(--navy);
}

.g1-offset-chip:hover {
  border-color: var(--gold);
}

.g1-offset-chip:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/* «Напомнить» submit — same as .btn-choose */
.btn-g1-submit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-family: var(--font-sans);
  font-size: var(--fz-action);
  font-weight: var(--fw-semibold);
  color: var(--navy);
  background: var(--gold-btn);
  border: 1px solid var(--gold-btn);
  border-radius: var(--radius-btn);
  padding: var(--space-xs) var(--space-md);
  min-height: 44px;
  cursor: pointer;
  transition: background var(--duration-fast) var(--easing-standard),
              border-color var(--duration-fast) var(--easing-standard),
              color var(--duration-fast) var(--easing-standard);
}

.btn-g1-submit:hover {
  background: var(--navy);
  border-color: var(--navy);
  color: var(--gold-light);
}

.btn-g1-submit:focus-visible {
  outline: 2px solid var(--navy);
  outline-offset: 2px;
}

.btn-g1-submit:disabled {
  opacity: 0.6;
  cursor: not-allowed;
}

/* Confirmation step */
.g1-optin-confirm-text {
  font-family: var(--font-sans);
  font-size: var(--fz-body);
  font-weight: var(--fw-regular);
  line-height: var(--lh-body);
  color: var(--color-muted);
  margin: 0;
}

/* Inline error */
.g1-optin-error {
  font-family: var(--font-sans);
  font-size: var(--fz-small, 0.875rem);
  color: var(--color-error, #c0392b);
  margin-top: var(--space-sm);
}

/* ── Skip link (screen reader / keyboard first user) ─────────────────────── */

.skip-link {
  position: absolute;
  top: -9999px;
  left: var(--space-md);
  /* Above the sticky .site-header (z-index 100) — a 100=100 tie left the
     focused link painted UNDER the navy bar (seamless-nav WG 2026-07-08). */
  z-index: 110;
  padding: var(--space-xs) var(--space-sm);
  background: var(--color-surface);
  color: var(--color-text);
  font-size: var(--fz-action);
  font-weight: var(--fw-bold);
  border: 2px solid var(--color-focus-ring);
  border-radius: var(--radius-sm);
  text-decoration: none;
}

.skip-link:focus {
  top: var(--space-sm);
}

/* ═══════════════════════════════════════════════════════════════════════════
 * BREAKPOINT: 360px — Standard mobile (full layout)
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Restore guillemets for <q> elements.
 * Add horizontal breathing room to cards.
 * Increase card internal padding slightly.
 */

@media (min-width: 360px) {

  q {
    quotes: "\00AB" "\00BB";
  }

  .page {
    width: min(var(--max-content-width), calc(100% - (2 * var(--space-lg))));
  }

  .card {
    padding: var(--space-lg);
    gap: var(--space-md);
  }

  /* card-image zone removed (правка #2) — no compensating margins needed */

  .card-gift-name {
    font-size: var(--fz-gift-name);
  }

  /* value-frame visible at 360px+ */
  .card-value-frame {
    display: block;
  }

}

/* ═══════════════════════════════════════════════════════════════════════════
 * BREAKPOINT: 768px — Tablet / Desktop (3-column card grid)
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Правка #3 (2026-06-06): сразу 3 колонки начиная с 768px — горизонтальный ряд.
 * Правка #4: subgrid для выравнивания блоков по горизонтали между карточками.
 *
 * Cards switch to 3-column grid with gap.
 * Larger page padding. Slightly larger typography.
 */

@media (min-width: 768px) {

  .page {
    width: min(var(--max-content-width), calc(100% - (2 * var(--space-xl))));
    padding-block: var(--space-xl) var(--space-4xl);
  }

  .hero {
    padding-block: var(--space-xl) var(--space-2xl);
    margin-bottom: var(--space-2xl);
  }

  /*
   * 3-column grid — all 3 preview cards in one horizontal row (правка #3).
   * align-items: stretch — all cards in a row have equal height.
   */
  .cards {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: var(--space-lg);
    padding: var(--space-xl) 0;
    align-items: stretch;
  }

  /* Reset mobile margin-bottom; cards are independent items with grid gap */
  .card {
    margin-bottom: 0;
    padding: var(--space-lg);
    border-radius: 11px;
    /* flex-column so card-actions can be pushed to bottom */
    display: flex;
    flex-direction: column;
  }

  /*
   * Правка #4: structural symmetry across cards in horizontal row.
   *
   * Strategy A — CSS subgrid (Chrome 117+, Firefox 71+, Safari 16+):
   * Each card uses grid-template-rows: subgrid to inherit parent row tracks.
   * The parent .cards defines 6 named row bands; each card's inner elements
   * map onto those bands — guaranteeing horizontal alignment.
   *
   * Strategy B — flex-column fallback (all browsers):
   * card-hook / card-answer / card-teaser each have flex: 0 0 auto.
   * card-actions gets margin-top: auto to push buttons to the card bottom.
   * This ensures buttons are always at the bottom of equal-height cards.
   *
   * Both strategies work simultaneously; subgrid takes precedence in
   * supporting browsers for pixel-perfect inter-card alignment.
   */

  /* Parent subgrid row tracks: 6 bands matching card anatomy */
  .cards {
    grid-template-rows: repeat(6, auto);
  }

  /* Each card spans all 6 row bands and participates in subgrid */
  @supports (grid-template-rows: subgrid) {
    .cards {
      /* 6 row bands: slot-label / hook / answer / teaser / price / actions */
      grid-template-rows: repeat(6, auto);
    }

    .card {
      /* Card spans 6 rows; inner elements align via subgrid */
      grid-row: span 6;
      grid-template-rows: subgrid;
      display: grid;
      gap: 0;
    }

    /* Map each inner element to its named subgrid row; gaps via margin */
    .card-slot-label    { grid-row: 1; align-self: start; }
    .card-hook          { grid-row: 2; align-self: start; }
    .card-answer        { grid-row: 3; align-self: start; }
    .card-teaser        { grid-row: 4; align-self: start; }
    .card-value-frame   { grid-row: 5; align-self: start; }
    .card-actions       { grid-row: 6; align-self: end; }
    /*
     * reject-chips: supplemental / on-demand (revealed by result_actions.js on
     * remix tap). It MUST be given an EXPLICIT row below the 6 content bands —
     * an unplaced item in a fully-occupied 6-row subgrid auto-collapses onto an
     * occupied row and overlaps the buttons (founder phone bug 2026-07-01,
     * visible at ≥768px). Pin it to row 7, full width, and extend ONLY the
     * active card's span to 7 (via :has) so the 6-row cross-card alignment
     * contract stays intact and sibling cards are never stretched.
     * .card-slot-error is absent in normal cards (only in is_template_fallback
     * branch) — no grid-row assignment needed; it auto-flows correctly.
     */
    .reject-chips { grid-column: 1 / -1; grid-row: 7; align-self: start; }
    .cards .card:has(.reject-chips:not([hidden])) { grid-row: span 7; }

    /*
     * add-details-door (UX-audit #1 fix 2026-07-08): the «добавь деталей» door
     * now lives INSIDE the card (result_actions.js appends it as a card child).
     * Like reject-chips it MUST get an EXPLICIT row below the 6 content bands —
     * an unplaced item in a 6-row subgrid collapses onto an occupied row. It
     * SHARES row 7 with the reject-chips (a second implicit row 8 is fragile in
     * subgrid and left an empty-row gap) — the two are never usefully visible at
     * once, so the door is hidden while the reject-chips are open (the user is
     * re-remixing; the door returns after the swap). Full width; extend ONLY a
     * card that has the door to span 7 (via :has) so the cross-card alignment
     * contract holds and sibling cards are never stretched.
     */
    .add-details-door { grid-column: 1 / -1; grid-row: 7; align-self: start; }
    .cards .card:has(.add-details-door) { grid-row: span 7; }
    .cards .card:has(.reject-chips:not([hidden])) .add-details-door { display: none; }
  }

  /* Flex fallback: push actions to card bottom regardless of content length */
  .card .card-actions {
    margin-top: auto;
  }

  /* Override any 3rd-card span override from previous rules */
  .cards .card:nth-child(3):last-child {
    grid-column: auto;
    max-width: none;
  }

}

/* ═══════════════════════════════════════════════════════════════════════════
 * BREAKPOINT: 1024px — Desktop (wider padding, larger gap)
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * 3-column grid already active from 768px.
 * At 1024px: wider page container + larger card gap + larger card padding.
 */

@media (min-width: 1024px) {

  .page {
    width: min(var(--max-content-width), calc(100% - (2 * var(--space-3xl))));
  }

  .cards {
    gap: var(--space-xl);
    padding: var(--space-xl) 0;
  }

  .card {
    padding: var(--space-xl);
  }

  /* Slightly larger gift name on desktop */
  .card-gift-name {
    font-size: var(--fz-gift-name);
  }

}

/* ═══════════════════════════════════════════════════════════════════════════
 * SMALL MOBILE OVERRIDES (<360px)
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Applied as max-width queries to override base styles for very small screens.
 * These must come AFTER the base styles to win specificity.
 */

@media (max-width: 359px) {

  .page {
    width: calc(100% - (2 * var(--space-sm)));
  }

  /* Smaller padding at 320px — avoid content touching screen edge */
  .card {
    padding: var(--space-sm) var(--space-md);
  }

  /* card-image zone removed (правка #2) — no margin compensation needed */

  /* Hard floor: 22px (1.375rem) gift name at very small screens */
  .card-gift-name {
    font-size: var(--fz-gift-name-small);
  }

  /* WG-1 (2026-05-23): value-frame always visible — removed @media hide per D2 spec */
  /* Previously hidden at <360px; now always block */
  .card-value-frame {
    display: block;
  }

  /* Collapse buy-paths to tight list */
  .card-buy-paths {
    gap: 2px;
  }

  /* Smaller hero title at very small viewport */
  .hero-title {
    font-size: 1.375rem;
  }

  /* Wrap action buttons more aggressively */
  .card-actions {
    flex-direction: column;
    gap: var(--space-xs);
  }

  .btn-remix,
  .btn-share {
    width: 100%;
    text-align: center;
    padding: var(--space-sm);
  }

}

/* ═══════════════════════════════════════════════════════════════════════════
 * ACCESSIBILITY — FOCUS INDICATORS
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Global focus-visible rule: 2px solid focus ring, 2px offset.
 * Never outline: none without a replacement.
 * Specific overrides for interactive elements are above.
 */

:focus-visible {
  outline: 2px solid var(--color-focus-ring);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Remove default outline for elements with custom :focus-visible rules above */
.card-buy-paths a:focus,
.btn-remix:focus,
.btn-share:focus {
  /* Suppressed in favour of :focus-visible; accessibility preserved */
  outline: none;
}

/* ═══════════════════════════════════════════════════════════════════════════
 * ACCESSIBILITY — REDUCED MOTION
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Disables all transitions and animations for users who have set
 * prefers-reduced-motion in their OS accessibility settings.
 */

@media (prefers-reduced-motion: reduce) {

  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }

}

/* ═══════════════════════════════════════════════════════════════════════════
 * PRINT STYLESHEET
 * ═══════════════════════════════════════════════════════════════════════════
 *
 * Clean print: just the cards, no navigation, no action buttons.
 * Avoid background colours/images (save toner).
 * Force black text on white background.
 */

@media print {

  body {
    background: #ffffff;
    color: #000000;
    font-size: 11pt;
  }

  .hero {
    border-bottom: 1px solid #cccccc;
    padding-bottom: 12pt;
    margin-bottom: 12pt;
  }

  .hero-title {
    font-size: 18pt;
    color: #000000;
  }

  .cards {
    display: block;
  }

  .card {
    border: 1px solid #cccccc;
    padding: 12pt;
    margin-bottom: 12pt;
    break-inside: avoid;
    box-shadow: none;
  }

  /* Hide interactive / non-content elements */
  .card-actions,
  .btn-remix,
  .btn-share {
    display: none;
  }

  .card-gift-name {
    font-size: 16pt;
    color: #000000;
  }

  .card-hook-line {
    color: #333333;
  }

  .card-why-them {
    color: #444444;
  }

  .card-buy-paths a {
    color: #000000;
    text-decoration: underline;
  }

  /* Show URL after links for print */
  .card-buy-paths a::after {
    content: " (" attr(href) ")";
    font-size: 8pt;
    color: #666666;
    word-break: break-all;
  }

}

/* ── Site chrome: flow mode (entry unification 2026-06-12) ─────────────── */

/*
 * chrome_mode="flow" (quiz wizard): the shared footer partial
 * (_site_footer.html) replaces the nav-links column with the brand slogan
 * «Подарцев · личный консьерж в мире подарков» — nav links are muted
 * mid-flow exits (founder-ratified). The column reuses .site-footer__col--nav
 * alignment (right on desktop, centred on mobile).
 */
.site-footer__slogan {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--fz-footer);
  /* --gold-light on navy = 5.99:1 — WCAG AA */
  color: var(--gold-light);
  text-align: right;
}

@media (max-width: 767px) {
  .site-footer__slogan {
    text-align: center;
  }
}

/* ── D-25 «Сохранить к дате» gesture (стр.2) ──────────────────────────── */

/*
 * Quiet/ghost save-to-date affordance placed below the ВРУЧИТЬ value block.
 * Deliberately understated — must not compete with the «Где найти» links or
 * the «Показать кому-то» button. No hyphens (project-wide rule, 2026-06-14).
 */

.d25-save-gesture {
  margin-top: var(--space-lg);
  padding-top: var(--space-md);
  border-top: 1px solid var(--color-border);
  /* FIX 2 (2026-07-02): centre the «напомнить»/SAVED block on the page
     (founder: «блок напомнить — отцентровать по странице»). text-align centres
     every inline/inline-block child (button, .ics link, headings, URL, hints);
     the flex groups below get an explicit justify-content: center. */
  text-align: center;
}

/* FIX 2 (2026-07-02): centre the flex control rows — text-align does not affect
   flex layout, so the reminder opt-in, the offset chips, and the date actions
   need justify-content: center to sit centred on the page. */
.d25-remind-choice,
.d25-offset-chips,
.d25-date-actions {
  justify-content: center;
}

/* Ghost quiet button — same visual weight as a text link, not an action CTA */
.btn-save-to-date {
  display: inline-block;
  background: transparent;
  border: 1px solid var(--color-accent);
  color: var(--color-accent);
  font-family: var(--font-sans);
  font-size: 0.9rem;
  padding: 0.45em 1.1em;
  border-radius: var(--radius-card);
  cursor: pointer;
  transition: background var(--duration-fast) var(--easing-out),
              color var(--duration-fast) var(--easing-out);
  hyphens: none;
}

.btn-save-to-date:hover,
.btn-save-to-date:focus-visible {
  background: var(--color-accent);
  color: #fff;
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Subtext line under the button — quiet caption */
.d25-save-subtext {
  margin: var(--space-xs) 0 0;
  font-family: var(--font-sans);
  font-size: 0.8rem;
  color: var(--color-muted);
  hyphens: none;
}

/* Date step */
.d25-date-label {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  color: var(--color-muted);
  margin-bottom: var(--space-xs);
  hyphens: none;
}

.d25-date-input {
  font-family: var(--font-sans);
  font-size: 1rem;
  border: 1px solid var(--color-border);
  border-radius: var(--radius-card);
  padding: 0.35em 0.6em;
  color: var(--color-text);
  background: var(--color-bg);
  margin-bottom: var(--space-sm);
  width: 100%;
  max-width: 18rem;
  hyphens: none;
}

/* Offset chips (mirrors g1_optin.css chip pattern) */
.d25-offset-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-bottom: var(--space-sm);
}

.d25-offset-chip {
  background: transparent;
  border: 1px solid var(--color-border);
  border-radius: 999px;
  font-family: var(--font-sans);
  font-size: 0.8rem;
  padding: 0.25em 0.8em;
  cursor: pointer;
  color: var(--color-text);
  transition: border-color var(--duration-fast) var(--easing-out),
              background var(--duration-fast) var(--easing-out);
  hyphens: none;
}

.d25-offset-chip--selected,
.d25-offset-chip[aria-pressed="true"] {
  border-color: var(--color-accent);
  background: var(--color-accent);
  color: #fff;
}

/* Date action buttons */
.d25-date-actions {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs);
  margin-top: var(--space-xs);
}

.btn-d25-submit {
  background: var(--color-accent);
  color: #fff;
  border: none;
  border-radius: var(--radius-card);
  font-family: var(--font-sans);
  font-size: 0.9rem;
  padding: 0.45em 1.1em;
  cursor: pointer;
  hyphens: none;
}

.btn-d25-submit:hover,
.btn-d25-submit:focus-visible {
  opacity: 0.88;
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

.btn-d25-nodate {
  background: transparent;
  border: none;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  color: var(--color-muted);
  padding: 0.45em 0.6em;
  cursor: pointer;
  text-decoration: underline;
  hyphens: none;
}

.btn-d25-nodate:hover,
.btn-d25-nodate:focus-visible {
  color: var(--color-text);
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Confirm text */
.d25-confirm-text {
  font-family: var(--font-sans);
  font-size: 0.9rem;
  color: var(--color-text);
  margin: 0;
  hyphens: none;
}

/* Deep-link button (anonymous bind-required path) */
.d25-bind-link {
  display: inline-block;
  margin-top: var(--space-xs);
  background: var(--color-accent);
  color: #fff;
  border-radius: var(--radius-card);
  font-family: var(--font-sans);
  font-size: 0.9rem;
  padding: 0.45em 1.1em;
  text-decoration: none;
  hyphens: none;
}

.d25-bind-link:hover,
.d25-bind-link:focus-visible {
  opacity: 0.88;
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* Inline error message */
.d25-error {
  font-family: var(--font-sans);
  font-size: 0.85rem;
  color: #b00020;
  margin: var(--space-xs) 0 0;
  hyphens: none;
}

/* T7: save-in-progress spinner — centred under the date actions */
.d25-save-spinner {
  margin: var(--space-sm, 12px) auto 0;
}

/* T3 (W1): hold-state line so the anon tab doesn't look frozen after the jump */
.d25-hold-state {
  font-family: var(--font-sans);
  font-size: 0.85rem;
  color: var(--color-muted, #6b675c);
  margin: var(--space-xs) 0 0;
  hyphens: none;
}

/* T4: copyable bot @-handle fallback (no deep-link) — tap-to-select */
.d25-bot-handle {
  font-family: var(--font-sans);
  font-size: 0.95rem;
  color: var(--color-accent);
  margin: var(--space-xs) 0 0;
  -webkit-user-select: all;
  user-select: all;
}

/* ── Save re-sequence (2026-07-01) — SAVED step + reminder channels ──────── */

/* «Сохранено ✓» heading */
.d25-saved-heading {
  font-family: var(--font-sans);
  font-size: 1rem;
  font-weight: var(--fw-semibold, 600);
  color: var(--color-text);
  margin: 0 0 var(--space-sm, 12px);
  hyphens: none;
}

/* Private bookmark block «только для вас» (Save ≠ Share) */
.d25-private-link {
  margin: 0 0 var(--space-md, 16px);
}
.d25-private-link-label {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.8rem;
  color: var(--color-muted, #6b675c);
  margin-bottom: 4px;
}
.d25-private-url {
  display: block;
  font-family: var(--font-sans);
  font-size: 0.85rem;
  color: var(--color-text);
  word-break: break-all;
  -webkit-user-select: all;
  user-select: all;
  padding: 6px 8px;
  background: rgba(0, 45, 91, 0.04);
  border-radius: var(--radius-card, 8px);
}
.btn-d25-copy-self {
  margin-top: 6px;
  background: transparent;
  border: 1px solid var(--color-accent);
  border-radius: var(--radius-card, 8px);
  color: var(--color-accent);
  font-family: var(--font-sans);
  font-size: 0.82rem;
  padding: 0.35em 0.9em;
  cursor: pointer;
  hyphens: none;
}
.btn-d25-copy-self:hover,
.btn-d25-copy-self:focus-visible {
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
.d25-private-hint {
  font-family: var(--font-sans);
  font-size: 0.8rem;
  color: var(--color-muted, #6b675c);
  margin: 6px 0 0;
  hyphens: none;
}

/* Optional reminder opt-in (the ONLY door to the date-picker) */
.d25-remind-choice {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-xs, 8px);
  align-items: center;
}
.btn-d25-remind {
  background: var(--color-accent);
  color: #fff;
  border: none;
  border-radius: var(--radius-card, 8px);
  font-family: var(--font-sans);
  font-size: 0.9rem;
  padding: 0.45em 1.1em;
  cursor: pointer;
  hyphens: none;
}
.btn-d25-remind:hover,
.btn-d25-remind:focus-visible {
  opacity: 0.88;
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
.btn-d25-remind-decline {
  background: transparent;
  border: none;
  color: var(--color-muted, #6b675c);
  font-family: var(--font-sans);
  font-size: 0.85rem;
  padding: 0.45em 0.6em;
  cursor: pointer;
  text-decoration: underline;
  hyphens: none;
}
.btn-d25-remind-decline:hover,
.btn-d25-remind-decline:focus-visible {
  color: var(--color-text);
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}

/* PRIMARY reminder — .ics «Добавить в календарь» */
.btn-d25-ics {
  display: inline-block;
  margin-top: var(--space-xs, 8px);
  background: var(--color-accent);
  color: #fff;
  border-radius: var(--radius-card, 8px);
  font-family: var(--font-sans);
  font-size: 0.92rem;
  font-weight: var(--fw-semibold, 600);
  padding: 0.5em 1.2em;
  text-decoration: none;
  hyphens: none;
}
.btn-d25-ics:hover,
.btn-d25-ics:focus-visible {
  opacity: 0.9;
  outline: 2px solid var(--color-accent);
  outline-offset: 2px;
}
.d25-ics-hint {
  font-family: var(--font-sans);
  font-size: 0.8rem;
  color: var(--color-muted, #6b675c);
  margin: 6px 0 0;
  hyphens: none;
}

/* SECONDARY, DEMOTED Telegram line — quieter, below the .ics primary */
.d25-tg-secondary {
  margin-top: var(--space-md, 16px);
  padding-top: var(--space-sm, 12px);
  border-top: 1px solid rgba(0, 0, 0, 0.06);
}
.d25-tg-secondary-text {
  font-family: var(--font-sans);
  font-size: 0.82rem;
  color: var(--color-muted, #6b675c);
  margin: 0;
  hyphens: none;
}

/* ══════════════════════════════════════════════════════════════════════════
 * Подарцев signature spinner — gold orbital comet on a cream core.
 *
 * Premium, calm, brand-true: a single gold comet (bright head → fading tail)
 * sweeps a hairline gold track while a small gold pip at the centre breathes.
 * Reads «we're carefully searching», not a generic wheel-of-doom. GPU-only
 * (transform/opacity); honours prefers-reduced-motion (spin → calm breath).
 *
 * Used by the per-card REMIX loading overlay below; authored as a standalone
 * component so first-gen / other surfaces can adopt it later.
 * ══════════════════════════════════════════════════════════════════════════ */
.pod-spinner {
  --pod-spinner-size: 48px;
  --pod-spinner-ring: 3px;
  position: relative;
  width: var(--pod-spinner-size);
  height: var(--pod-spinner-size);
  flex: none;
}

/* Hairline track — a faint full gold ring the comet travels along. */
.pod-spinner::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  border: var(--pod-spinner-ring) solid var(--gold-light, #c4a776);
  opacity: 0.22;
}

/* The comet — a conic gold sweep masked down to a ring band, rotating.
 * Bright head at 0°, tail fading to transparent by ~210°, then a clean gap —
 * so the rotation reads as a comet chasing the ring, not a static circle. */
.pod-spinner::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(
    from 0deg,
    var(--gold, #a68751) 0deg,
    var(--gold-light, #c4a776) 40deg,
    rgba(166, 135, 81, 0) 210deg,
    rgba(166, 135, 81, 0) 360deg
  );
  -webkit-mask: radial-gradient(farthest-side,
    transparent calc(100% - var(--pod-spinner-ring)), #000 calc(100% - var(--pod-spinner-ring)));
  mask: radial-gradient(farthest-side,
    transparent calc(100% - var(--pod-spinner-ring)), #000 calc(100% - var(--pod-spinner-ring)));
  animation: podSpinnerSweep 1.05s linear infinite;
}

/* Centre pip — a small gold dot that gently breathes (life without spin). */
.pod-spinner-pip {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 5px;
  height: 5px;
  margin: -2.5px 0 0 -2.5px;
  border-radius: 50%;
  background: var(--gold, #a68751);
  animation: podSpinnerPip 1.7s ease-in-out infinite;
}

@keyframes podSpinnerSweep { to { transform: rotate(360deg); } }
@keyframes podSpinnerPip {
  0%, 100% { transform: scale(0.65); opacity: 0.45; }
  50%      { transform: scale(1);    opacity: 1; }
}

/* ── Per-card REMIX loading overlay ─────────────────────────────────────────
 * Shown over the single card being re-rolled while DeepSeek regenerates it
 * (5–15s). A frosted cream veil lets the old card text recede; the signature
 * spinner + an italic Playfair line make «работает, не зависло» unmistakable.
 * Anchored to the card via `.card.is-remixing { position: relative }`.
 * Injected/removed by result_actions.js. */
.card.is-remixing {
  position: relative;
}

.card-remix-overlay {
  position: absolute;
  inset: 0;
  z-index: 6;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-md, 1rem);
  /* Match the card's own corner radius (11px) exactly. */
  border-radius: inherit;
  /* Warm paper veil — the old card recedes to a faint ghost so the spinner +
   * caption own the focus; blur is progressive enhancement over the opacity. */
  background: rgba(255, 253, 249, 0.93);
  -webkit-backdrop-filter: blur(4px) saturate(1.04);
  backdrop-filter: blur(4px) saturate(1.04);
  padding: var(--space-md, 1rem);
  text-align: center;
  animation: podRemixVeilIn var(--duration-mid, 200ms) var(--easing-out, ease) both;
}

.card-remix-caption {
  margin: 0;
  max-width: 22ch;
  font-family: var(--font-serif);
  font-style: italic;
  font-weight: var(--fw-regular, 400);
  font-size: var(--fz-hook-line, 0.9375rem);
  line-height: var(--lh-heading, 1.2);
  letter-spacing: 0.01em;
  color: var(--gold-on-light, #8e6f39);
  transition: opacity 0.4s var(--easing-standard, ease);
}

.card-remix-caption.is-fading {
  opacity: 0;
}

@keyframes podRemixVeilIn { from { opacity: 0; } to { opacity: 1; } }

/* Reduced-motion: drop the sweep + veil fade; keep a calm breathing ring so
 * activity is still signalled without vestibular-triggering rotation. */
@media (prefers-reduced-motion: reduce) {
  .pod-spinner::after { animation: none; opacity: 0; }
  .pod-spinner::before { animation: podSpinnerBreath 1.6s ease-in-out infinite; }
  .pod-spinner-pip { animation: podSpinnerBreath 1.6s ease-in-out infinite; }
  .card-remix-overlay { animation: none; }
  .card-remix-caption { transition: none; }
}

@keyframes podSpinnerBreath {
  0%, 100% { opacity: 0.25; }
  50%      { opacity: 0.7; }
}
