/* ==========================================================================
   Production-only additions on top of the redesign prototype CSS.
   The prototype hides the nav on mobile with no replacement; prod needs a menu.
   ========================================================================== */

/* reset the browser default <button> chrome (grey buttonface) — every styled
   button in the design sets its own background/border via a class, so bare
   buttons like inactive .cfgtab / .faq__q must not show the UA grey fill */
button { background: none; border: 0; }

.appbar__burger {
    display: none;
    place-items: center;
    width: 44px; height: 44px;
    border-radius: 999px;
    border: 1px solid var(--line-strong);
    color: var(--ink);
    background: transparent;
}
.appbar__burger:hover { border-color: var(--brand-line); background: var(--brand-soft); }

/* Admin top nav carries more (and longer) labels than the public navbar — keep
   each label on one line and let whole items wrap, so "История запросов" never
   splits mid-word. */
.admin-shell .appnav { flex-wrap: wrap; row-gap: 4px; }
.admin-shell .appnav a { white-space: nowrap; }

@media (max-width: 900px) {
    .appbar__burger { display: inline-grid; }
    .appbar--open .appnav {
        display: flex;
        position: fixed;
        left: var(--gutter); right: var(--gutter);
        top: 72px;
        flex-direction: column;
        align-items: stretch;
        gap: 4px;
        padding: 12px;
        border: 1px solid var(--line);
        border-radius: var(--r-md);
        background: var(--surface-solid);
        box-shadow: var(--shadow-pop);
        z-index: 60;
    }
    .appbar--open .appnav a { padding: 12px 14px; }
}

/* mobile header: the price pill has no room next to the lockup + Оферта + burger
   and overlapped the logo on phones. Drop it on small screens (the price is also
   shown in the hero), and let the lockup subtitle truncate instead of overflowing. */
@media (max-width: 640px) {
    .appbar__price { display: none; }
    .appbar__inner { gap: 12px; }
    .lockup__sub { overflow: hidden; text-overflow: ellipsis; }
}

/* mobile layout (burger): the Оферта button squeezed the logo, so move it into
   the burger menu — the phone header keeps just logo + theme toggle + burger. */
.appnav__offer { display: none; }
@media (max-width: 900px) {
    .appbar__offer { display: none; }
    .appnav__offer { display: block; }
}

/* hero stats: three short numbers — on phones lay them out as an even 3-up row
   instead of the awkward 2 + 1 wrap. */
@media (max-width: 560px) {
    .hero__stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 26px; }
    .hero__stats .stat { min-width: 0; }
    .hero__stats .stat__n { font-size: 1.5rem; }
    .hero__stats .stat__l { font-size: 0.72rem; }
}

/* seamless marquee: the track's flex `gap` was not included in the -50%
   translate, so the source strip jumped on every loop. Drop the gap and space
   items via their own padding, so -50% lands exactly on the duplicated-copy
   boundary and the loop is invisible. */
.marquee__track { gap: 0; animation-name: marqueeProd; }
.marquee__item { padding-inline: 18px; }
/* Keep the source strip ALWAYS full: welcome.blade renders 6 copies of the sources;
   scroll by exactly one copy (-100%/6) so it loops seamlessly and never shows an
   empty tail, even on wide monitors (stays full up to ~5 copies ≈ 3700px). */
@keyframes marqueeProd { from { transform: translateX(0); } to { transform: translateX(calc(-100% / 6)); } }

/* faq +/- glyph: keep it optically centred in its circle (no baseline drift) */
.faq__sign { line-height: 1; }
/* copy-to-clipboard icon is an SVG now — drop the old glyph font sizing */
.copyable__ic { font-size: 0; }

/* keep the floating-rail bottom padding off pages that have no proto rail */
body.no-proto { padding-bottom: 0; }

/* admin config tab panels: only the active one is shown (brand.js toggles .is-active) */
[data-admin-tab-panel] { display: none; }
[data-admin-tab-panel].is-active { display: grid; gap: 18px; }

/* install wizard: only the active step panel / db-connection group is shown */
[data-install-step-panel] { display: none; }
[data-install-step-panel].is-active { display: grid; gap: 16px; }
[data-connection-group] { display: none; }
[data-connection-group].is-active { display: grid; gap: 12px; }
.install__form { min-width: 0; }

/* admin config fields: the 2-col grid + full-width/textarea spans come from the
   prototype's `g2 cfg__fields` (app.css .g2 + admin.css .cfg__fields). Only the
   env-key monospace needs a nudge on top of the vendored styles. */
.cfield__env code { font-family: ui-monospace, monospace; }

/* overview status pills: never let a long path/domain push past the card edge */
.ovpill .micro { overflow-wrap: anywhere; }

/* branding preview: the macket centres the logo box via place-items, but a
   multi-line empty-state placeholder stays left-aligned inside the centred span
   — centre the text and give it breathing room so the dashed box reads clean */
.branding__logo { text-align: center; padding: 10px; }
.branding__logo .micro { max-width: 100%; }

/* profile widget states (brand.js toggles these) */
.profile-widget.is-warning { border-color: rgba(255,176,46,0.34); }
.profile-widget.is-error { border-color: rgba(255,90,95,0.34); }
.profile-widget.is-ready { border-color: var(--brand-line); }
.profile-methods { display: flex; gap: 6px; flex-wrap: wrap; }
.profile-methods span { font-size: 12px; font-weight: 700; color: var(--ink-soft); border: 1px solid var(--line); border-radius: 999px; padding: 4px 10px; }

/* lightweight modal (balance top-up, etc.) */
.admin-modal { position: fixed; inset: 0; z-index: 90; display: grid; place-items: center; padding: 20px; }
.admin-modal[hidden] { display: none; }
.admin-modal__backdrop { position: absolute; inset: 0; background: rgba(6,8,15,0.7); backdrop-filter: blur(4px); }
.admin-modal__dialog { position: relative; width: min(520px, 100%); display: grid; gap: 16px; padding: clamp(20px,2.6vw,30px); border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--surface-solid); box-shadow: var(--shadow-pop); }
.admin-modal__head { display: flex; align-items: flex-start; justify-content: space-between; gap: 14px; }
.admin-modal__form { display: grid; gap: 14px; }
.admin-modal__actions { display: flex; gap: 10px; flex-wrap: wrap; }
.admin-modal__feedback { padding: 12px 14px; border-radius: var(--r-sm); border: 1px solid var(--line); background: var(--surface-2); font-size: 0.9rem; }
.admin-modal__feedback.is-success { border-color: rgba(31,209,138,0.34); background: var(--ok-soft); color: var(--ok); }
.admin-modal__feedback.is-error { border-color: rgba(255,90,95,0.34); background: var(--stop-soft); color: var(--stop); }

/* stat minicard (offer hero, etc.) — also defined in admin.css, mirrored here
   so it works on public pages where admin.css is not loaded */
.minicard { padding: 16px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--bg-deep); display: grid; gap: 6px; align-content: start; }
.minicard > .micro { font-size: 12px; }
.minicard > strong { font-weight: 800; font-size: 1rem; line-height: 1.3; }

/* sticky save bar */
.cfg-save { position: sticky; bottom: 14px; display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; margin-top: 18px; padding: 16px 20px; border: 1px solid var(--line-strong); border-radius: var(--r-md); background: color-mix(in srgb, var(--surface-solid) 92%, transparent); backdrop-filter: blur(12px); box-shadow: var(--shadow-pop); }
.cfg-save p { margin: 0; }

/* ==========================================================================
   Scroll-reveal hardening.
   The prototype hides .reveal (opacity:0) and lets JS add .is-in on scroll.
   On the real server a deferred redesign.js download can run a beat late, which
   left above-the-fold content (notably the hero) blank for ~1–2s. Drive the
   entrance with a pure-CSS animation so content is NEVER gated on JS timing;
   the JS .is-in path still works as a progressive enhancement, and
   prefers-reduced-motion (handled in styles.css) still forces it visible.
   ========================================================================== */
@media (prefers-reduced-motion: no-preference) {
    .reveal { animation: prodRevealIn 0.7s var(--ease) both; }
    .reveal[data-d="1"] { animation-delay: 0.07s; }
    .reveal[data-d="2"] { animation-delay: 0.14s; }
    .reveal[data-d="3"] { animation-delay: 0.21s; }
    .reveal[data-d="4"] { animation-delay: 0.28s; }
    .reveal[data-d="5"] { animation-delay: 0.35s; }
    .reveal.is-in { animation: none; opacity: 1; transform: none; }
}
@keyframes prodRevealIn {
    from { opacity: 0; transform: translateY(22px); }
    to   { opacity: 1; transform: none; }
}

/* ==========================================================================
   Theme toggle (shared component: public appbar + admin appbar/login).
   Loaded by both public.blade.php and admin.blade.php via prod.css.
   Light shows the moon (click → dark); dark shows the sun (click → light).
   ========================================================================== */
.themetoggle { display: grid; place-items: center; width: 40px; height: 40px; flex: none; border-radius: 999px; border: 1px solid var(--line-strong); background: transparent; color: var(--ink-soft); cursor: pointer; transition: border-color .15s, background .15s, color .15s, transform .15s; }
.themetoggle:hover { border-color: var(--brand-line); background: var(--brand-soft); color: var(--brand-ink); transform: translateY(-1px); }
.themetoggle__moon, .themetoggle__sun { display: block; }
.themetoggle__sun { display: none; }
:root[data-theme="dark"] .themetoggle__moon { display: none; }
:root[data-theme="dark"] .themetoggle__sun { display: block; }

/* Header overlap fix: keep the action group at its intrinsic width and let the
   brand name clip with an ellipsis, so a long brand name (or the extra toggle)
   never runs underneath Оферта/burger on narrow screens. */
.appbar__right { flex: none; }
.lockup__copy { min-width: 0; }
.lockup__name { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* uploaded brand logo in the lockup — bigger than the default chevron and adapts
   to the logo's aspect ratio; tightened on phones so it never crowds the name. */
.lockup__logo { max-height: 46px; max-width: 180px; width: auto; height: auto; object-fit: contain; display: block; }
@media (max-width: 560px) { .lockup__logo { max-height: 38px; max-width: 140px; } }

/* "TRONK is flaky right now" soft banner — shown to customer and operator while
   upstream is unstable (auto-clears). Amber, full-width, non-blocking. */
.svcbanner {
  background: #fff4e5;
  color: #7a4a00;
  border-bottom: 1px solid rgba(0, 0, 0, 0.08);
  padding: 10px 16px;
  font-size: 13px;
  line-height: 1.45;
  text-align: center;
}
:root[data-theme="dark"] .svcbanner {
  background: #3a2a10;
  color: #ffcf8a;
  border-bottom-color: rgba(255, 255, 255, 0.08);
}

/* Long order UUID in the row summary must wrap inside its column, never bleed
   over the neighbouring "Данные" column. */
.otable__uuid { min-width: 0; max-width: 100%; }
.otable__uuid .copyable__t { white-space: normal; overflow-wrap: anywhere; word-break: break-all; }

/* SMTP test result inside the modal — spinner while sending, green ok / red error. */
.admin-modal__feedback.is-loading { display: flex; align-items: center; }
.admin-modal__spin { display: inline-block; width: 15px; height: 15px; margin-right: 9px; border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: tronkSpin 0.7s linear infinite; flex: none; }
@keyframes tronkSpin { to { transform: rotate(360deg); } }
.admin-modal__feedback.is-ok { color: #1c6b39; font-weight: 600; }
.admin-modal__feedback.is-error { color: #8a2020; font-weight: 600; }
:root[data-theme="dark"] .admin-modal__feedback.is-ok { color: #7fe0a3; }
:root[data-theme="dark"] .admin-modal__feedback.is-error { color: #ff9d9d; }
