/* LexyBooster — onboarding v2.
 *
 * Built on the Soft Card design system (public/css/soft-card.css), the same one
 * the paywall and the rest of the app use. This file previously carried its own
 * dark indigo palette — #6366f1 on a #1a1a2e gradient — inherited from an app
 * shell that no longer exists. Onboarding is the first screen a new user ever
 * sees, so the product introduced itself in one set of colours and then swapped
 * to a completely different one the moment onboarding finished.
 *
 * EVERY COLOUR HERE IS A TOKEN. Nothing is hardcoded, and that is what makes
 * dark mode work for free: soft-card redefines the same variables under
 * [data-theme="dark"], so this file follows the app instead of maintaining a
 * parallel palette that drifts out of sync.
 *
 * Full-screen rather than a modal: onboarding is the whole experience at this
 * point, and a dialog floating over a half-loaded app reads as an interruption.
 * Sizing uses dvh so the layout does not jump while mobile Safari animates its
 * URL bar. */

.lexy-ob-open { overflow: hidden; }

.lexy-ob {
    position: fixed;
    inset: 0;
    z-index: 9999;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 16px;
    /* Opaque, because this is the app's first screen and not an overlay on top
     * of one. The tint at the top is the accent at its softest: enough that a
     * flat fill does not read as a blank page, faint enough not to compete
     * with the CTA. background-color is declared separately as the fallback —
     * if the gradient is ever dropped the screen still has a surface. */
    background-color: var(--sc-bg, #EEF2EE);
    background-image: radial-gradient(120% 70% at 50% 0%,
        var(--sc-accent-soft, #DDEDE3) 0%,
        var(--sc-bg, #EEF2EE) 58%);
    color: var(--sc-ink, #16221A);
    font-family: var(--sc-font, 'Inter', system-ui, -apple-system, sans-serif);
    overflow-y: auto;
}

.lexy-ob-card {
    display: flex;
    flex-direction: column;
    width: 100%;
    max-width: 460px;
    min-height: min(640px, calc(100dvh - 32px));
    box-sizing: border-box;
}

/* Dark-mode button reset — REQUIRED, not cosmetic.
 *
 * style.css (~line 427) paints EVERY <button> on the page in dark mode with a
 * gradient background and a coloured border, excluding only five app-specific
 * classes. Every interactive element in onboarding is a <button>: the back
 * arrow, the answer tiles, "show all languages", the CTA, "don't remind me".
 * Left alone, the whole screen turns into a field of identical purple pills
 * with no visual hierarchy at all — the back arrow looks exactly as clickable
 * as the primary action.
 *
 * Five :not() clauses put that selector at specificity (0,6,1); a class rule
 * here is (0,1,0) and loses. Hence !important, scoped to .lexy-ob so nothing
 * outside onboarding is affected — and every component below has to restate
 * its own background-color and border for the same reason.
 *
 * Restating background-COLOR matters: the global rule uses the `background`
 * shorthand, which resets background-color to transparent as a side effect, so
 * removing only background-image leaves a button with no fill at all. That
 * exact bug shipped on the paywall once. */
.lexy-ob button {
    background-image: none !important;
    border: 0 !important;
    box-shadow: none !important;
}

/* Progress -------------------------------------------------------------- */

.lexy-ob-top {
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 4px 0 22px;
}

.lexy-ob-back {
    flex: 0 0 auto;
    width: 34px; height: 34px;
    display: flex; align-items: center; justify-content: center;
    font-size: 26px; line-height: 1;
    color: var(--sc-muted, #6F7E73);
    background: transparent;
    border: 0;
    border-radius: var(--sc-r-sm, 12px);
    cursor: pointer;
}
.lexy-ob .lexy-ob-back {
    color: var(--sc-muted, #6F7E73) !important;
    background-color: transparent !important;
}
.lexy-ob .lexy-ob-back:hover {
    color: var(--sc-ink, #16221A) !important;
    background-color: var(--sc-surface-alt, #F5F8F5) !important;
}
.lexy-ob-back:focus-visible {
    outline: 2px solid var(--sc-accent, #3F8A5C);
    outline-offset: 2px;
}
.lexy-ob-top > span { width: 34px; }

.lexy-ob-progress {
    flex: 1 1 auto;
    height: 6px;
    background: var(--sc-accent-soft, #DDEDE3);
    border-radius: var(--sc-r-pill, 999px);
    overflow: hidden;
}
.lexy-ob-progress i {
    display: block;
    height: 100%;
    background: var(--sc-accent, #3F8A5C);
    border-radius: var(--sc-r-pill, 999px);
    transition: width 260ms cubic-bezier(0.2, 0.8, 0.3, 1);
}

/* Body ------------------------------------------------------------------- */

.lexy-ob-body {
    flex: 1 1 auto;
    display: flex;
    flex-direction: column;
    animation: lexy-ob-in 220ms cubic-bezier(0.2, 0.8, 0.3, 1);
}

@keyframes lexy-ob-in {
    from { opacity: 0; transform: translateY(10px); }
    to   { opacity: 1; transform: translateY(0); }
}

.lexy-ob-eyebrow {
    margin: 0 0 8px;
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.09em;
    text-transform: uppercase;
    color: var(--sc-accent, #3F8A5C);
}
/* soft-card-overrides.css paints every <p> in dark mode with
 * `color: var(--sc-ink) !important` at (0,1,1). The eyebrow, the lead and the
 * note are all <p>, and all three are meant to sit BELOW the title in the
 * hierarchy — without this they come out at full ink weight and everything on
 * the screen shouts equally loudly. */
.lexy-ob .lexy-ob-eyebrow { color: var(--sc-accent, #3F8A5C) !important; }

.lexy-ob-title {
    margin: 0 0 10px;
    font-size: 26px;
    line-height: 1.24;
}

/* Typography reset — REQUIRED, not cosmetic.
 *
 * soft-card-overrides.css is injected by a script at runtime (index.html ~277),
 * so it always lands after this file and paints every h1/h2 with a display
 * font, its own letter-spacing, and `color: var(--sc-ink) !important` plus the
 * matching -webkit-text-fill-color. A plain class selector loses to !important,
 * so these have to match it; they stay scoped to the overlay.
 *
 * The colour is now the same token the override wants, so this is no longer
 * fighting it — but it is kept explicit because -webkit-text-fill-color beats
 * `color` in WebKit, and a future override that sets one without the other
 * would silently blank the headings. That has already happened once. */
.lexy-ob h1,
.lexy-ob h2,
.lexy-ob .lexy-ob-title {
    color: var(--sc-ink, #16221A) !important;
    -webkit-text-fill-color: var(--sc-ink, #16221A) !important;
    font-family: var(--sc-font-display, 'Fraunces', Georgia, serif) !important;
    font-weight: 600 !important;
    letter-spacing: -0.01em !important;
    text-shadow: none !important;
    background: none !important;
}

/* The target date sits inside the plan-summary <h2>, so it needs its own rule
 * to escape the heading colour above. */
.lexy-ob .lexy-ob-date {
    color: var(--sc-accent, #3F8A5C) !important;
    -webkit-text-fill-color: var(--sc-accent, #3F8A5C) !important;
    white-space: nowrap;
}

.lexy-ob-lead {
    margin: 0 0 22px;
    font-size: 15px;
    line-height: 1.5;
}
.lexy-ob .lexy-ob-lead { color: var(--sc-ink-soft, #3F4D44) !important; }
.lexy-ob .lexy-ob-lead strong { color: var(--sc-ink, #16221A) !important; }

.lexy-ob-note {
    margin: 16px 0 0;
    font-size: 12.5px;
    line-height: 1.45;
}
.lexy-ob .lexy-ob-note { color: var(--sc-muted, #6F7E73) !important; }

/* Options ---------------------------------------------------------------- */

.lexy-ob-grid {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 10px;
    margin-bottom: 8px;
}

.lexy-ob-list { display: flex; flex-direction: column; gap: 10px; margin-bottom: 8px; }

.lexy-ob-option {
    padding: 15px 16px;
    font-size: 15px;
    font-family: inherit;
    text-align: left;
    color: var(--sc-ink, #16221A);
    background: var(--sc-surface, #FFFFFF);
    border: 2px solid var(--sc-line, #DCE5DE);
    border-radius: var(--sc-r-md, 16px);
    cursor: pointer;
    transition: border-color 120ms ease, background-color 120ms ease, transform 80ms ease;
}
.lexy-ob .lexy-ob-option {
    color: var(--sc-ink, #16221A) !important;
    background-color: var(--sc-surface, #FFFFFF) !important;
    border: 2px solid var(--sc-line, #DCE5DE) !important;
}
.lexy-ob .lexy-ob-option:hover { border-color: var(--sc-accent, #3F8A5C) !important; }
.lexy-ob .lexy-ob-option.is-selected {
    border-color: var(--sc-accent, #3F8A5C) !important;
    background-color: var(--sc-accent-soft, #DDEDE3) !important;
}
.lexy-ob-option:active { transform: scale(0.985); }
.lexy-ob-option:focus-visible {
    outline: 2px solid var(--sc-accent, #3F8A5C);
    outline-offset: 2px;
}
.lexy-ob-option.is-wide { width: 100%; }

/* Two-line options (target level, self-assessment).
 *
 * The hint is not decoration: "средний уровень" means whatever the reader wants
 * it to mean, and the answer feeds the word count the plan and the paywall are
 * both sold on. The example underneath is what makes the choice repeatable.
 *
 * Colours are set with !important and -webkit-text-fill-color is reset for the
 * same reason as every other rule in this file: css/soft-card-overrides.css is
 * injected by script, therefore lands after this stylesheet, and repaints text
 * to near-black — invisible on this overlay. WebKit ranks -webkit-text-fill-color
 * above color, so setting only color leaves the hint unreadable on iOS. */
.lexy-ob-option.has-hint {
    display: flex;
    flex-direction: column;
    gap: 3px;
    line-height: 1.35;
}
.lexy-ob .lexy-ob-option .lexy-ob-option-label {
    /* No colour of its own: the button above already forces ink with
     * !important, and the label is the only thing that should read as the
     * button's own text. One less literal for scripts/check-design-tokens.js
     * to count, and one less place to keep in sync. */
    font-weight: 600;
}
.lexy-ob .lexy-ob-option .lexy-ob-option-hint {
    font-size: 13px;
    font-weight: 400;
    /* Deliberately no hex fallback — the design-token gate counts those, and
     * an undefined --sc-muted degrades to the inherited ink here: the hint
     * loses its contrast step but stays perfectly readable. */
    color: var(--sc-muted) !important;
    -webkit-text-fill-color: var(--sc-muted);
}

/* Language search / expand ------------------------------------------------ */

.lexy-ob-search {
    width: 100%;
    box-sizing: border-box;
    margin: 0 0 14px;
    padding: 13px 15px;
    font-size: 15px;
    font-family: inherit;
    -webkit-appearance: none;
    appearance: none;
    border-radius: var(--sc-r-md, 16px);
}
/* style.css gives every dark-mode <input> a translucent near-black fill, an
 * inset shadow and a backdrop-filter at (0,1,1). Two classes outrank that, but
 * the declarations are restated with !important anyway because a later rule
 * with a bare `input` selector would otherwise be enough to bring the old look
 * back. */
.lexy-ob .lexy-ob-search {
    color: var(--sc-ink, #16221A) !important;
    background: var(--sc-surface, #FFFFFF) !important;
    border: 2px solid var(--sc-line, #DCE5DE) !important;
    box-shadow: none !important;
    backdrop-filter: none !important;
    -webkit-backdrop-filter: none !important;
}
.lexy-ob .lexy-ob-search::placeholder { color: var(--sc-muted, #6F7E73) !important; }
.lexy-ob .lexy-ob-search:focus {
    outline: none;
    border-color: var(--sc-accent, #3F8A5C) !important;
    box-shadow: none !important;
}

.lexy-ob-more {
    display: block;
    width: 100%;
    margin-top: 12px;
    padding: 12px;
    font-size: 14px;
    font-weight: 600;
    font-family: inherit;
    background: none;
    border: 0;
    cursor: pointer;
}
.lexy-ob .lexy-ob-more {
    color: var(--sc-accent, #3F8A5C) !important;
    background-color: transparent !important;
}
.lexy-ob .lexy-ob-more:hover { text-decoration: underline; }

.lexy-ob-empty { margin: 14px 0 0; text-align: center; }

/* With the full list open the grid scrolls rather than pushing the CTA off
   screen — on a long list the primary action must stay reachable. */
.lexy-ob-grid { max-height: 52dvh; overflow-y: auto; }
.lexy-ob-grid::-webkit-scrollbar { width: 6px; }
.lexy-ob-grid::-webkit-scrollbar-thumb {
    background: var(--sc-line, #DCE5DE);
    border-radius: var(--sc-r-pill, 999px);
}

/* Buttons ---------------------------------------------------------------- */

.lexy-ob-primary,
.lexy-ob-secondary {
    display: block;
    width: 100%;
    margin-top: auto;
    padding: 16px 18px;
    font-size: 16px;
    font-weight: 600;
    font-family: inherit;
    border: 0;
    /* Pill, matching the paywall CTA and .sc-btn-pill — the two moments where
     * the app asks for a commitment should look like the same button. */
    border-radius: var(--sc-r-pill, 999px);
    cursor: pointer;
    transition: transform 100ms ease, opacity 120ms ease, filter 120ms ease;
}
.lexy-ob-primary {
    color: var(--sc-accent-ink, #FFFFFF);
    background: var(--sc-accent, #3F8A5C);
}
.lexy-ob .lexy-ob-primary {
    color: var(--sc-accent-ink, #FFFFFF) !important;
    background-color: var(--sc-accent, #3F8A5C) !important;
}
.lexy-ob-secondary {
    margin-top: 10px;
    color: var(--sc-ink, #16221A);
    background: var(--sc-surface, #FFFFFF);
}
.lexy-ob .lexy-ob-secondary {
    color: var(--sc-ink, #16221A) !important;
    background-color: var(--sc-surface, #FFFFFF) !important;
    border: 1px solid var(--sc-line, #DCE5DE) !important;
}
.lexy-ob-primary:hover, .lexy-ob-secondary:hover { transform: translateY(-1px); }
.lexy-ob-primary:hover { filter: brightness(1.05); }
.lexy-ob-primary:focus-visible, .lexy-ob-secondary:focus-visible {
    outline: 2px solid var(--sc-ink, #16221A);
    outline-offset: 2px;
}
.lexy-ob-primary:disabled, .lexy-ob-secondary:disabled {
    opacity: 0.6; cursor: default; transform: none; filter: none;
}
/* Stacked auth buttons: only the first keeps the auto top margin. */
.lexy-ob-primary ~ .lexy-ob-secondary { margin-top: 10px; }

.lexy-ob-skip {
    display: block;
    width: 100%;
    margin-top: 14px;
    padding: 10px;
    font-size: 14px;
    font-family: inherit;
    background: none;
    border: 0;
    text-decoration: underline;
    cursor: pointer;
}
.lexy-ob .lexy-ob-skip {
    color: var(--sc-muted, #6F7E73) !important;
    background-color: transparent !important;
}
.lexy-ob .lexy-ob-skip:hover { color: var(--sc-ink, #16221A) !important; }

/* Plan summary ----------------------------------------------------------- */

.lexy-ob-stats {
    display: grid;
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 10px;
    margin: 22px 0 6px;
}
.lexy-ob-stats > div {
    padding: 14px 8px;
    text-align: center;
    background: var(--sc-surface, #FFFFFF);
    border: 1px solid var(--sc-line, #DCE5DE);
    border-radius: var(--sc-r-md, 16px);
}
.lexy-ob-stats strong {
    display: block;
    font-size: 22px;
    font-weight: 700;
    color: var(--sc-ink, #16221A);
}
.lexy-ob-stats span { font-size: 12px; color: var(--sc-muted, #6F7E73); }

/* Taster lesson ---------------------------------------------------------- */

.lexy-ob-word {
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 10px;
    margin: 28px 0;
    padding: 34px 20px;
    text-align: center;
    background: var(--sc-surface, #FFFFFF);
    border: 1px solid var(--sc-line, #DCE5DE);
    border-radius: var(--sc-r-xl, 24px);
}
.lexy-ob-word-main {
    font-family: var(--sc-font-display, 'Fraunces', Georgia, serif);
    font-size: 32px;
    font-weight: 600;
    line-height: 1.2;
    letter-spacing: -0.01em;
    color: var(--sc-ink, #16221A);
}
.lexy-ob-word-tr { font-size: 19px; color: var(--sc-accent, #3F8A5C); }
.lexy-ob-word-ex {
    margin-top: 6px;
    font-size: 14px;
    font-style: italic;
    color: var(--sc-muted, #6F7E73);
}

/* Plan-building screen --------------------------------------------------- */

.lexy-ob-spinner {
    width: 42px; height: 42px;
    margin: 40px auto 24px;
    border: 3px solid var(--sc-accent-soft, #DDEDE3);
    border-top-color: var(--sc-accent, #3F8A5C);
    border-radius: 50%;
    animation: lexy-ob-spin 800ms linear infinite;
}
@keyframes lexy-ob-spin { to { transform: rotate(360deg); } }

.lexy-ob-ticker { margin: 0; padding: 0; list-style: none; text-align: center; }
.lexy-ob-ticker li {
    padding: 7px 0;
    font-size: 14px;
    color: var(--sc-muted, #6F7E73);
    opacity: 0;
    animation: lexy-ob-tick 400ms ease-out forwards;
}
.lexy-ob-ticker li:nth-child(1) { animation-delay: 120ms; }
.lexy-ob-ticker li:nth-child(2) { animation-delay: 600ms; }
.lexy-ob-ticker li:nth-child(3) { animation-delay: 1080ms; }
@keyframes lexy-ob-tick { to { opacity: 1; } }

/* Small phones ----------------------------------------------------------- */

@media (max-width: 380px) {
    .lexy-ob-title { font-size: 23px; }
    .lexy-ob-word-main { font-size: 27px; }
    .lexy-ob-grid { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
    .lexy-ob-body, .lexy-ob-ticker li { animation: none; opacity: 1; }
    .lexy-ob-progress i { transition: none; }
    .lexy-ob-spinner { animation-duration: 2s; }
    .lexy-ob-primary:hover, .lexy-ob-secondary:hover { transform: none; }
}
