/* css/components.css — shared UI primitives, "Function" system.
   Aged Paper card surfaces and the "ink label" button shape (bordered,
   squared-off rectangles rather than a generic filled pill) are the
   tactile signature; elevation comes from color-stepping (Parchment ->
   Aged Paper), never from shadow — the two approved shadow recipes below
   are reserved for genuinely floating elements (modals). Button direction
   chosen from 3 options presented in the 2026-08-24 design review — see
   .impeccable/critique/2026-08-24T18-51-02Z__index-html.md. Buttons never
   get text-transform: uppercase — Chromium's accessible-name computation
   reflects CSS text-transform, which would break every
   getByRole(..., { name: 'Купить' })-style test in this suite. */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  padding: 12px 24px;
  border-radius: var(--radius-button); /* was the 40px pill — squared-off "ink label" shape */
  font-family: var(--font-body);
  font-weight: 700; /* was 600 — carries the shape's boldness without uppercase */
  letter-spacing: 0.01em;
  font-size: 1rem;
  cursor: pointer;
  text-decoration: none;
  border: 1.5px solid transparent;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease, transform 0.15s ease;
}
.btn--primary {
  background-color: var(--color-accent-fill);
  /* The Primary CTA Button component spec calls for white text; the Agent
     Prompt Guide's own example shows parchment instead (#fef9ef), which
     also clears AA but by a much thinner margin (~4.59:1 vs ~4.81:1 for
     white against this terracotta) — white is the safer, still spec-valid
     choice. */
  color: #ffffff;
  border-color: transparent; /* the "ink" contour was dropped — flat terracotta fill only */
}
/* Hover inverts to a solid ink fill with terracotta text — a real color
   swap instead of a brightness filter, reserved for the primary button
   since it's used sparingly (one per viewport, per the system's own rule). */
.btn--primary:hover { background-color: var(--color-text); border-color: var(--color-text); color: var(--color-accent-fill); }
.btn--primary:active { transform: translateY(1px); }
.btn--primary:disabled { opacity: 0.5; cursor: not-allowed; }

/* Arrow glyph inside a CTA's own text (hero "Выбрать урок →") — wrapped in
   its own span so only the arrow shifts on hover, not the whole button. */
.btn__arrow { display: inline-block; transition: transform 0.15s ease; }
.btn:hover .btn__arrow { transform: translateX(4px); }

/* Outlined Secondary Button — same shape as .btn--primary, ink border and
   text instead of a filled ground. Used by the checkout promo "Применить"
   button today. */
.btn--outline {
  background: transparent;
  color: var(--color-text);
  border-color: var(--color-text);
}
.btn--outline:hover { background: rgba(42, 43, 47, 0.06); }

/* Shared circular icon button — closes the checkout modal and the mobile
   product modal identically instead of one bare "×" and one filled circle
   (a P2 finding from the 2026-08-24 design review: 5 different "dismiss"
   affordances existed for what were really only a couple of distinct
   concepts). */
.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 40px; height: 40px; border-radius: var(--radius-pill);
  background: transparent; border: 1.5px solid var(--color-text);
  color: var(--color-text); font-size: 1.1rem; line-height: 1;
  cursor: pointer; transition: background-color 0.15s ease;
}
.icon-btn:hover { background: rgba(42, 43, 47, 0.06); }
/* `display: inline-flex` above overrides the UA stylesheet's `[hidden] {
   display: none }` (author styles win regardless of selector order), so
   any icon-btn toggled via the `hidden` attribute needs it restated here. */
.icon-btn[hidden] { display: none; }

/* Base pill shape reused by the product-card type/level badges
   (product-card__badge, product-card__level-badge — js/catalog.js) as
   `class="badge product-card__badge"` etc.; those add only positioning
   and level-specific color on top. The about-section regalia badges that
   used to be the other consumer are gone (2026-08-25, replaced by
   .about__facts), but this one is very much still live — don't delete it
   again without grepping for `class="badge ` (with a trailing space) first,
   not just the exact string `class="badge"`. */
.badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 12px;
  border-radius: var(--radius-pill);
  font-size: var(--text-label);
  font-weight: 600;
  letter-spacing: -0.28px;
  text-transform: uppercase;
  background: var(--color-bg);
  border: 1px solid var(--color-taupe);
  color: var(--color-text);
}

.card {
  background: var(--color-accent-detail);
  border-radius: var(--radius-card);
  padding: var(--space-3);
  /* no box-shadow — Function's elevation is color-stepping (Parchment ->
     Aged Paper), not drop shadow; see .checkout-modal for the one
     genuinely-floating exception, which uses the system's approved
     shadow-xl recipe instead of an ad-hoc shadow. */
}

.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: var(--space-2); }
.field label { font-weight: 600; font-size: var(--text-caption); }
.field__input {
  font-family: var(--font-body);
  font-size: 1rem;
  letter-spacing: -0.37px;
  padding: 12px 20px;
  border: 1px solid var(--color-ash);
  border-radius: var(--radius-pill);
  background: var(--color-bg);
  color: var(--color-text);
  width: 100%;
  min-width: 0; /* text inputs default to min-width:auto, which stops them
                   shrinking below their content size inside a flex row and
                   pushes sibling buttons past the viewport edge */
  box-sizing: border-box;
}
.field__input::placeholder { color: var(--color-muted); }
.field__input:focus { outline: none; box-shadow: 0 0 0 3px rgba(176,90,54,0.2); }
.field__checkbox-row { display: flex; align-items: flex-start; gap: 8px; font-size: var(--text-caption); }

/* Consistent keyboard-focus ring across every interactive element — text
   fields already had their own box-shadow ring above; this covers
   buttons, links, and native selects the same way. */
a:focus-visible,
button:focus-visible,
select:focus-visible,
input:focus-visible {
  outline: none;
  box-shadow: 0 0 0 3px rgba(176,90,54,0.35);
  border-radius: 4px;
}

.price {
  font-family: var(--font-heading);
  font-weight: 500;
  font-size: 1.4rem;
  color: var(--color-text);
}
.price--struck {
  font-family: var(--font-body);
  text-decoration: line-through;
  opacity: 0.55;
  font-weight: 500;
  font-size: 1rem;
  margin-right: 8px;
}

/* checkout modal (used by js/commerce-mock.js) — the one place a real
   drop shadow is appropriate: a floating overlay, using the system's
   approved shadow-xl recipe rather than an ad-hoc one. */
.checkout-overlay {
  position: fixed; inset: 0;
  background: rgba(42,43,47,0.45);
  display: flex; align-items: center; justify-content: center;
  z-index: 1000;
  padding: var(--space-2);
  /* The modal can be taller than short/landscape viewports (e.g. phone
     landscape) — without this, it overflows the centered flex container
     with no scrollable ancestor and its bottom (incl. the "Купить" button)
     becomes unreachable. */
  overflow-y: auto;
  /* scroll-behavior is inherited from html (base.css sets it to `smooth`
     for #anchor nav links) — left as-is here, this container's own
     scrolling would animate too, which can make an auto-scroll-into-view
     interaction (see the identical note on .product-modal__scroll) retry
     forever instead of settling. */
  scroll-behavior: auto;
}
.checkout-modal {
  max-width: 420px; width: 100%; position: relative;
  background: var(--color-bg);
  box-shadow: rgba(42,43,47,0.1) 12px 32px 80px 0px;
  /* Centers via margin instead of relying purely on flex alignment, which
     clipped the top of the modal when the flex container had to shrink it
     on short viewports (see .checkout-overlay overflow-y above). */
  margin: auto;
}
.checkout-note { font-size: var(--text-caption); opacity: 0.75; }
.checkout-items { list-style: none; margin: 0 0 var(--space-2); padding: 0; font-size: var(--text-caption); }
.checkout-items li { display: flex; justify-content: space-between; gap: 12px; padding: 4px 0; }
.checkout-total { font-weight: 600; font-size: var(--text-body-lg); margin: var(--space-2) 0; }
.checkout-close {
  position: absolute; top: 12px; right: 12px;
}
.checkout-modal > .field__input { margin-bottom: var(--space-2); }
.checkout-error { font-size: var(--text-caption); min-height: 1.2em; margin: 0 0 var(--space-1); color: crimson; }
.checkout-promo-row { display: flex; gap: 8px; margin-bottom: 6px; }
.checkout-promo-message { font-size: var(--text-caption); min-height: 1.2em; margin: 0 0 var(--space-2); }

/* Labeled placeholder image (js/placeholder-img.js renderPlaceholder) — a
   class instead of an inline `style="aspect-ratio:..."` attribute so a
   strict CSP style-src (no 'unsafe-inline') doesn't silently drop the
   sizing. Only 4/3 is ever used in practice (no call site overrides it),
   so one fixed class covers every current placeholder. */
.media-placeholder { aspect-ratio: 4/3; width: 100%; object-fit: cover; border-radius: 16px; }
